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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
ZODB
Commits
252350a3
Commit
252350a3
authored
Apr 25, 2005
by
Tim Peters
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Interface repairs, of many kinds.
parent
00b57dc5
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 @
252350a3
...
...
@@ -330,7 +330,7 @@ class Connection(ExportImport, object):
# the savepoint, then they won't have _p_oid or _p_jar after
# they've been unadded. This will make the code in _abort
# confused.
self
.
_abort
()
...
...
@@ -341,7 +341,7 @@ class Connection(ExportImport, object):
def
_abort
(
self
):
"""Abort a transaction and forget all changes."""
for
obj
in
self
.
_registered_objects
:
oid
=
obj
.
_p_oid
assert
oid
is
not
None
...
...
@@ -444,7 +444,7 @@ class Connection(ExportImport, object):
self
.
_commit_savepoint
(
transaction
)
# No need to call _commit since savepoint did.
else
:
self
.
_commit
(
transaction
)
...
...
@@ -575,7 +575,7 @@ class Connection(ExportImport, object):
if
self
.
_savepoint_storage
is
not
None
:
self
.
_abort_savepoint
()
self
.
_storage
.
tpc_abort
(
transaction
)
# Note: If we invalidate a non-justifiable object (i.e. a
...
...
@@ -626,11 +626,15 @@ class Connection(ExportImport, object):
def
tpc_finish
(
self
,
transaction
):
"""Indicate confirmation that the transaction is done."""
def
callback
(
tid
):
d
=
{}
for
oid
in
self
.
_modified
:
d
[
oid
]
=
1
d
=
dict
.
fromkeys
(
self
.
_modified
)
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
.
_tpc_cleanup
()
...
...
@@ -653,7 +657,7 @@ class Connection(ExportImport, object):
# Transaction-manager synchronization -- ISynchronizer
##########################################################################
##########################################################################
# persistent.interfaces.IPersistentDatamanager
...
...
@@ -815,7 +819,7 @@ class Connection(ExportImport, object):
# registering the object, because joining may take a
# savepoint, and the savepoint should not reflect the change
# to the object.
if
self
.
_needs_to_join
:
self
.
_txn_mgr
.
get
().
join
(
self
)
self
.
_needs_to_join
=
False
...
...
@@ -823,7 +827,7 @@ class Connection(ExportImport, object):
if
obj
is
not
None
:
self
.
_registered_objects
.
append
(
obj
)
# persistent.interfaces.IPersistentDatamanager
##########################################################################
...
...
@@ -1076,11 +1080,11 @@ class TmpStore:
def
__init__
(
self
,
base_version
,
storage
):
self
.
_storage
=
storage
for
method
in
(
'getName'
,
'new_oid'
,
'modifiedInVersion'
,
'getSize'
,
'getName'
,
'new_oid'
,
'modifiedInVersion'
,
'getSize'
,
'undoLog'
,
'versionEmpty'
,
'sortKey'
,
):
setattr
(
self
,
method
,
getattr
(
storage
,
method
))
self
.
_base_version
=
base_version
self
.
_file
=
tempfile
.
TemporaryFile
()
# position: current file position
...
...
@@ -1089,7 +1093,7 @@ class TmpStore:
# index: map oid to pos of last committed version
self
.
index
=
{}
self
.
creating
=
[]
def
__len__
(
self
):
return
len
(
self
.
index
)
...
...
src/transaction/interfaces.py
View file @
252350a3
...
...
@@ -71,7 +71,8 @@ class ITransaction(zope.interface.Interface):
Objects with this interface may represent different transactions
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
(
...
...
@@ -123,29 +124,21 @@ class ITransaction(zope.interface.Interface):
"""
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*
making any changes: if the transaction has made any savepoints, then
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.
`datamanager` must provide the transactions.interfaces.IDataManager
interface.
"""
def
note
(
text
):
"""Add text to the transaction description.
If a description has already been set, text is added to the
end of the description following two newline characters.
Surrounding whitespace is stripped from text.
This modifies the `.description` attribute; see its docs for more
detail. First surrounding whitespace is stripped from `text`. If
`.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
=
"/"
):
"""Set the user name.
...
...
@@ -153,19 +146,23 @@ class ITransaction(zope.interface.Interface):
path should be provided if needed to further qualify the
identified user. This is a convenience method used by Zope.
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
):
"""Add extension data to the transaction.
name is the name of the extension property to set; value must
be a picklable value.
name is the name of the extension property to set, of Python type
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
which can be stored.
Storages record the extension data, as meta-data, when a transaction
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
):
"""Register a hook to call before the transaction is committed.
...
...
@@ -195,7 +192,6 @@ class ITransaction(zope.interface.Interface):
class
ITransactionDeprecated
(
zope
.
interface
.
Interface
):
"""Deprecated parts of the transaction API."""
# TODO: deprecated36
def
begin
(
info
=
None
):
"""Begin a new transaction.
...
...
@@ -207,6 +203,7 @@ class ITransactionDeprecated(zope.interface.Interface):
def
register
(
object
):
"""Register the given object for transaction control."""
class
IDataManager
(
zope
.
interface
.
Interface
):
"""Objects that manage transactional storage.
...
...
@@ -219,10 +216,6 @@ class IDataManager(zope.interface.Interface):
the transaction.
"""
# Two-phase commit protocol. These methods are called by the
# ITransaction object associated with the transaction being
# committed.
def
abort
(
transaction
):
"""Abort a transaction and forget all changes.
...
...
@@ -232,6 +225,11 @@ class IDataManager(zope.interface.Interface):
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
):
"""Begin commit of a transaction, starting the two-phase commit.
...
...
@@ -242,25 +240,13 @@ class IDataManager(zope.interface.Interface):
def
commit
(
transaction
):
"""Commit modifications to registered objects.
Save the object as part of the data to be made persistent if
the transaction commits.
Save changes to be made persistent if the transaction commits (if
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
errors occur it saves the objects in the storage.
"""
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.
This includes conflict detection and handling. If no conflicts or
errors occur, the data manager should be prepared to make the
changes persist when tpc_finish is called.
"""
def
tpc_vote
(
transaction
):
...
...
@@ -276,18 +262,27 @@ class IDataManager(zope.interface.Interface):
def
tpc_finish
(
transaction
):
"""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 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
serious error.
"""
def
tpc_abort
(
transaction
):
"""Abort a transaction.
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!
This is called by a transaction manager to end a two-phase commit on
the data manager. Abandon all changes to objects modified by this
transaction.
transaction is the ITransaction instance associated with the
transaction being committed.
This should never fail.
"""
def
sortKey
():
...
...
@@ -321,7 +316,7 @@ class IDataManagerSavepoint(zope.interface.Interface):
responsibility for, validity. It isn't the responsibility of
data-manager savepoints to prevent multiple rollbacks or rollbacks after
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.
"""
...
...
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