Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZODB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Nicolas Wavrant
ZODB
Commits
1f2211ca
Commit
1f2211ca
authored
Apr 25, 2005
by
Tim Peters
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge rev 30179 from 3.4 branch.
Interface repairs, of many kinds.
parent
73ed1e6f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
65 additions
and
66 deletions
+65
-66
src/ZODB/Connection.py
src/ZODB/Connection.py
+17
-13
src/transaction/interfaces.py
src/transaction/interfaces.py
+48
-53
No files found.
src/ZODB/Connection.py
View file @
1f2211ca
...
@@ -330,7 +330,7 @@ class Connection(ExportImport, object):
...
@@ -330,7 +330,7 @@ class Connection(ExportImport, object):
# the savepoint, then they won't have _p_oid or _p_jar after
# the savepoint, then they won't have _p_oid or _p_jar after
# they've been unadded. This will make the code in _abort
# they've been unadded. This will make the code in _abort
# confused.
# confused.
self
.
_abort
()
self
.
_abort
()
...
@@ -341,7 +341,7 @@ class Connection(ExportImport, object):
...
@@ -341,7 +341,7 @@ class Connection(ExportImport, object):
def
_abort
(
self
):
def
_abort
(
self
):
"""Abort a transaction and forget all changes."""
"""Abort a transaction and forget all changes."""
for
obj
in
self
.
_registered_objects
:
for
obj
in
self
.
_registered_objects
:
oid
=
obj
.
_p_oid
oid
=
obj
.
_p_oid
assert
oid
is
not
None
assert
oid
is
not
None
...
@@ -444,7 +444,7 @@ class Connection(ExportImport, object):
...
@@ -444,7 +444,7 @@ class Connection(ExportImport, object):
self
.
_commit_savepoint
(
transaction
)
self
.
_commit_savepoint
(
transaction
)
# No need to call _commit since savepoint did.
# No need to call _commit since savepoint did.
else
:
else
:
self
.
_commit
(
transaction
)
self
.
_commit
(
transaction
)
...
@@ -575,7 +575,7 @@ class Connection(ExportImport, object):
...
@@ -575,7 +575,7 @@ class Connection(ExportImport, object):
if
self
.
_savepoint_storage
is
not
None
:
if
self
.
_savepoint_storage
is
not
None
:
self
.
_abort_savepoint
()
self
.
_abort_savepoint
()
self
.
_storage
.
tpc_abort
(
transaction
)
self
.
_storage
.
tpc_abort
(
transaction
)
# Note: If we invalidate a non-justifiable object (i.e. a
# Note: If we invalidate a non-justifiable object (i.e. a
...
@@ -626,11 +626,15 @@ class Connection(ExportImport, object):
...
@@ -626,11 +626,15 @@ class Connection(ExportImport, object):
def
tpc_finish
(
self
,
transaction
):
def
tpc_finish
(
self
,
transaction
):
"""Indicate confirmation that the transaction is done."""
"""Indicate confirmation that the transaction is done."""
def
callback
(
tid
):
def
callback
(
tid
):
d
=
{}
d
=
dict
.
fromkeys
(
self
.
_modified
)
for
oid
in
self
.
_modified
:
d
[
oid
]
=
1
self
.
_db
.
invalidate
(
tid
,
d
,
self
)
self
.
_db
.
invalidate
(
tid
,
d
,
self
)
# It's important that the storage calls the passed function
# while it still has its lock. We don't want another thread
# to be able to read any updated data until we've had a chance
# to send an invalidation message to all of the other
# connections!
self
.
_storage
.
tpc_finish
(
transaction
,
callback
)
self
.
_storage
.
tpc_finish
(
transaction
,
callback
)
self
.
_tpc_cleanup
()
self
.
_tpc_cleanup
()
...
@@ -653,7 +657,7 @@ class Connection(ExportImport, object):
...
@@ -653,7 +657,7 @@ class Connection(ExportImport, object):
# Transaction-manager synchronization -- ISynchronizer
# Transaction-manager synchronization -- ISynchronizer
##########################################################################
##########################################################################
##########################################################################
##########################################################################
# persistent.interfaces.IPersistentDatamanager
# persistent.interfaces.IPersistentDatamanager
...
@@ -815,7 +819,7 @@ class Connection(ExportImport, object):
...
@@ -815,7 +819,7 @@ class Connection(ExportImport, object):
# registering the object, because joining may take a
# registering the object, because joining may take a
# savepoint, and the savepoint should not reflect the change
# savepoint, and the savepoint should not reflect the change
# to the object.
# to the object.
if
self
.
_needs_to_join
:
if
self
.
_needs_to_join
:
self
.
_txn_mgr
.
get
().
join
(
self
)
self
.
_txn_mgr
.
get
().
join
(
self
)
self
.
_needs_to_join
=
False
self
.
_needs_to_join
=
False
...
@@ -823,7 +827,7 @@ class Connection(ExportImport, object):
...
@@ -823,7 +827,7 @@ class Connection(ExportImport, object):
if
obj
is
not
None
:
if
obj
is
not
None
:
self
.
_registered_objects
.
append
(
obj
)
self
.
_registered_objects
.
append
(
obj
)
# persistent.interfaces.IPersistentDatamanager
# persistent.interfaces.IPersistentDatamanager
##########################################################################
##########################################################################
...
@@ -1076,11 +1080,11 @@ class TmpStore:
...
@@ -1076,11 +1080,11 @@ class TmpStore:
def
__init__
(
self
,
base_version
,
storage
):
def
__init__
(
self
,
base_version
,
storage
):
self
.
_storage
=
storage
self
.
_storage
=
storage
for
method
in
(
for
method
in
(
'getName'
,
'new_oid'
,
'modifiedInVersion'
,
'getSize'
,
'getName'
,
'new_oid'
,
'modifiedInVersion'
,
'getSize'
,
'undoLog'
,
'versionEmpty'
,
'sortKey'
,
'undoLog'
,
'versionEmpty'
,
'sortKey'
,
):
):
setattr
(
self
,
method
,
getattr
(
storage
,
method
))
setattr
(
self
,
method
,
getattr
(
storage
,
method
))
self
.
_base_version
=
base_version
self
.
_base_version
=
base_version
self
.
_file
=
tempfile
.
TemporaryFile
()
self
.
_file
=
tempfile
.
TemporaryFile
()
# position: current file position
# position: current file position
...
@@ -1089,7 +1093,7 @@ class TmpStore:
...
@@ -1089,7 +1093,7 @@ class TmpStore:
# index: map oid to pos of last committed version
# index: map oid to pos of last committed version
self
.
index
=
{}
self
.
index
=
{}
self
.
creating
=
[]
self
.
creating
=
[]
def
__len__
(
self
):
def
__len__
(
self
):
return
len
(
self
.
index
)
return
len
(
self
.
index
)
...
...
src/transaction/interfaces.py
View file @
1f2211ca
...
@@ -71,7 +71,8 @@ class ITransaction(zope.interface.Interface):
...
@@ -71,7 +71,8 @@ class ITransaction(zope.interface.Interface):
Objects with this interface may represent different transactions
Objects with this interface may represent different transactions
during their lifetime (.begin() can be called to start a new
during their lifetime (.begin() can be called to start a new
transaction using the same instance).
transaction using the same instance, although that example is
deprecated and will go away in ZODB 3.6).
"""
"""
user
=
zope
.
interface
.
Attribute
(
user
=
zope
.
interface
.
Attribute
(
...
@@ -123,29 +124,21 @@ class ITransaction(zope.interface.Interface):
...
@@ -123,29 +124,21 @@ class ITransaction(zope.interface.Interface):
"""
"""
def
join
(
datamanager
):
def
join
(
datamanager
):
"""Add a datamanager to the transaction.
"""Add a data
manager to the transaction.
If the data manager supports savepoints, it must call join *before*
`datamanager` must provide the transactions.interfaces.IDataManager
making any changes: if the transaction has made any savepoints, then
interface.
the transaction will take a savepoint of the data manager when join
is called, and this savepoint must reflect the state of the data
manager before any changes that caused the data manager to join the
transaction.
The datamanager must implement the
transactions.interfaces.IDataManager interface, and be
adaptable to ZODB.interfaces.IDataManager.
"""
"""
def
note
(
text
):
def
note
(
text
):
"""Add text to the transaction description.
"""Add text to the transaction description.
If a description has already been set, text is added to the
This modifies the `.description` attribute; see its docs for more
end of the description following two newline characters.
detail. First surrounding whitespace is stripped from `text`. If
Surrounding whitespace is stripped from text.
`.description` is currently an empty string, then the stripped text
becomes its value, else two newlines and the stripped text are
appended to `.description`.
"""
"""
# Unsure: does impl do the right thing with ''? Not clear what
# the "right thing" is.
def
setUser
(
user_name
,
path
=
"/"
):
def
setUser
(
user_name
,
path
=
"/"
):
"""Set the user name.
"""Set the user name.
...
@@ -153,19 +146,23 @@ class ITransaction(zope.interface.Interface):
...
@@ -153,19 +146,23 @@ class ITransaction(zope.interface.Interface):
path should be provided if needed to further qualify the
path should be provided if needed to further qualify the
identified user. This is a convenience method used by Zope.
identified user. This is a convenience method used by Zope.
It sets the .user attribute to str(path) + " " + str(user_name).
It sets the .user attribute to str(path) + " " + str(user_name).
This sets the `.user` attribute; see its docs for more detail.
"""
"""
def
setExtendedInfo
(
name
,
value
):
def
setExtendedInfo
(
name
,
value
):
"""Add extension data to the transaction.
"""Add extension data to the transaction.
name is the name of the extension property to set; value must
name is the name of the extension property to set, of Python type
be a picklable value.
str; value must be pickleable. Multiple calls may be made to set
multiple extension properties, provided the names are distinct.
Storage implementations may limit the amount of extension data
Storages record the extension data, as meta-data, when a transaction
which can be stored.
commits.
A storage may impose a limit on the size of extension data; behavior
is undefined if such a limit is exceeded (for example, a storage may
raise an exception, or remove `<name, value>` pairs).
"""
"""
# Unsure: is this allowed to cause an exception here, during
# the two-phase commit, or can it toss data silently?
def
beforeCommitHook
(
hook
,
*
args
,
**
kws
):
def
beforeCommitHook
(
hook
,
*
args
,
**
kws
):
"""Register a hook to call before the transaction is committed.
"""Register a hook to call before the transaction is committed.
...
@@ -195,7 +192,6 @@ class ITransaction(zope.interface.Interface):
...
@@ -195,7 +192,6 @@ class ITransaction(zope.interface.Interface):
class
ITransactionDeprecated
(
zope
.
interface
.
Interface
):
class
ITransactionDeprecated
(
zope
.
interface
.
Interface
):
"""Deprecated parts of the transaction API."""
"""Deprecated parts of the transaction API."""
# TODO: deprecated36
def
begin
(
info
=
None
):
def
begin
(
info
=
None
):
"""Begin a new transaction.
"""Begin a new transaction.
...
@@ -207,6 +203,7 @@ class ITransactionDeprecated(zope.interface.Interface):
...
@@ -207,6 +203,7 @@ class ITransactionDeprecated(zope.interface.Interface):
def
register
(
object
):
def
register
(
object
):
"""Register the given object for transaction control."""
"""Register the given object for transaction control."""
class
IDataManager
(
zope
.
interface
.
Interface
):
class
IDataManager
(
zope
.
interface
.
Interface
):
"""Objects that manage transactional storage.
"""Objects that manage transactional storage.
...
@@ -219,10 +216,6 @@ class IDataManager(zope.interface.Interface):
...
@@ -219,10 +216,6 @@ class IDataManager(zope.interface.Interface):
the transaction.
the transaction.
"""
"""
# Two-phase commit protocol. These methods are called by the
# ITransaction object associated with the transaction being
# committed.
def
abort
(
transaction
):
def
abort
(
transaction
):
"""Abort a transaction and forget all changes.
"""Abort a transaction and forget all changes.
...
@@ -232,6 +225,11 @@ class IDataManager(zope.interface.Interface):
...
@@ -232,6 +225,11 @@ class IDataManager(zope.interface.Interface):
that are not yet in a two-phase commit.
that are not yet in a two-phase commit.
"""
"""
# Two-phase commit protocol. These methods are called by the ITransaction
# object associated with the transaction being committed. The sequence
# of calls normally follows this regular expression:
# tpc_begin commit tpc_vote (tpc_finish | tpc_abort)
def
tpc_begin
(
transaction
):
def
tpc_begin
(
transaction
):
"""Begin commit of a transaction, starting the two-phase commit.
"""Begin commit of a transaction, starting the two-phase commit.
...
@@ -242,25 +240,13 @@ class IDataManager(zope.interface.Interface):
...
@@ -242,25 +240,13 @@ class IDataManager(zope.interface.Interface):
def
commit
(
transaction
):
def
commit
(
transaction
):
"""Commit modifications to registered objects.
"""Commit modifications to registered objects.
Save the object as part of the data to be made persistent if
Save changes to be made persistent if the transaction commits (if
the transaction commits.
tpc_finish is called later). If tpc_abort is called later, changes
must not persist.
This includes conflict detection and handling. If no conflicts or
This includes conflict detection and handling. If no conflicts or
errors occur it saves the objects in the storage.
errors occur, the data manager should be prepared to make the
"""
changes persist when tpc_finish is called.
def
tpc_abort
(
transaction
):
"""Abort a transaction.
This is called by a transaction manager to end a two-phase commit on
the data manager.
This is always called after a tpc_begin call.
transaction is the ITransaction instance associated with the
transaction being committed.
This should never fail.
"""
"""
def
tpc_vote
(
transaction
):
def
tpc_vote
(
transaction
):
...
@@ -276,18 +262,27 @@ class IDataManager(zope.interface.Interface):
...
@@ -276,18 +262,27 @@ class IDataManager(zope.interface.Interface):
def
tpc_finish
(
transaction
):
def
tpc_finish
(
transaction
):
"""Indicate confirmation that the transaction is done.
"""Indicate confirmation that the transaction is done.
Make all changes to objects modified by this transaction persist.
transaction is the ITransaction instance associated with the
transaction is the ITransaction instance associated with the
transaction being committed.
transaction being committed.
This should never fail. If this raises an exception, the
This should never fail.
If this raises an exception, the
database is not expected to maintain consistency; it's a
database is not expected to maintain consistency; it's a
serious error.
serious error.
"""
def
tpc_abort
(
transaction
):
"""Abort a transaction.
It's important that the storage calls the passed function
This is called by a transaction manager to end a two-phase commit on
while it still has its lock. We don't want another thread
the data manager. Abandon all changes to objects modified by this
to be able to read any updated data until we've had a chance
transaction.
to send an invalidation message to all of the other
connections!
transaction is the ITransaction instance associated with the
transaction being committed.
This should never fail.
"""
"""
def
sortKey
():
def
sortKey
():
...
@@ -321,7 +316,7 @@ class IDataManagerSavepoint(zope.interface.Interface):
...
@@ -321,7 +316,7 @@ class IDataManagerSavepoint(zope.interface.Interface):
responsibility for, validity. It isn't the responsibility of
responsibility for, validity. It isn't the responsibility of
data-manager savepoints to prevent multiple rollbacks or rollbacks after
data-manager savepoints to prevent multiple rollbacks or rollbacks after
transaction termination. Preventing invalid savepoint rollback is the
transaction termination. Preventing invalid savepoint rollback is the
responsibility of transaction rollbacks. Application code should never
responsibility of transaction rollbacks.
Application code should never
use data-manager savepoints.
use data-manager savepoints.
"""
"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment