[Zodb-checkins] SVN: ZODB/trunk/src/ Merge rev 30179 from 3.4 branch.

Tim Peters tim.one at comcast.net
Mon Apr 25 18:02:59 EDT 2005


Log message for revision 30180:
  Merge rev 30179 from 3.4 branch.
  
  Interface repairs, of many kinds.
  

Changed:
  U   ZODB/trunk/src/ZODB/Connection.py
  U   ZODB/trunk/src/transaction/interfaces.py

-=-
Modified: ZODB/trunk/src/ZODB/Connection.py
===================================================================
--- ZODB/trunk/src/ZODB/Connection.py	2005-04-25 22:02:07 UTC (rev 30179)
+++ ZODB/trunk/src/ZODB/Connection.py	2005-04-25 22:02:59 UTC (rev 30180)
@@ -330,8 +330,8 @@
         # 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()
 
         if self._savepoint_storage is not None:
@@ -341,7 +341,7 @@
 
     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 @@
             self._commit_savepoint(transaction)
 
             # No need to call _commit since savepoint did.
-            
+
         else:
             self._commit(transaction)
 
@@ -575,7 +575,7 @@
 
         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 @@
 
     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 @@
 
     # Transaction-manager synchronization -- ISynchronizer
     ##########################################################################
-    
+
     ##########################################################################
     # persistent.interfaces.IPersistentDatamanager
 
@@ -815,7 +819,7 @@
         # 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 @@
         if obj is not None:
             self._registered_objects.append(obj)
 
-    
+
     # persistent.interfaces.IPersistentDatamanager
     ##########################################################################
 
@@ -1076,11 +1080,11 @@
     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 @@
         # index: map oid to pos of last committed version
         self.index = {}
         self.creating = []
-                    
+
     def __len__(self):
         return len(self.index)
 

Modified: ZODB/trunk/src/transaction/interfaces.py
===================================================================
--- ZODB/trunk/src/transaction/interfaces.py	2005-04-25 22:02:07 UTC (rev 30179)
+++ ZODB/trunk/src/transaction/interfaces.py	2005-04-25 22:02:59 UTC (rev 30180)
@@ -71,7 +71,8 @@
 
     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 @@
         """
 
     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 @@
         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 ITransactionDeprecated(zope.interface.Interface):
     """Deprecated parts of the transaction API."""
 
-    # TODO: deprecated36
     def begin(info=None):
         """Begin a new transaction.
 
@@ -207,6 +203,7 @@
     def register(object):
         """Register the given object for transaction control."""
 
+
 class IDataManager(zope.interface.Interface):
     """Objects that manage transactional storage.
 
@@ -219,10 +216,6 @@
     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 @@
         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,27 +240,15 @@
     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.
+        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_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):
         """Verify that a data manager can commit the transaction.
 
@@ -276,18 +262,27 @@
     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.
+        """
 
-        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!
+    def tpc_abort(transaction):
+        """Abort a transaction.
+
+        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 @@
     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.
     """
 



More information about the Zodb-checkins mailing list