[Zodb-checkins] CVS: ZODB3/ZODB - Connection.py:1.76.4.1.2.1

Jeremy Hylton jeremy@zope.com
Fri, 1 Nov 2002 14:29:22 -0500


Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv21507/ZODB

Modified Files:
      Tag: ZODB3-deadlock-debug-branch
	Connection.py 
Log Message:
Two changes related to deadlock prevention.

Add a sortKey() method that delegates to the storage.

Remove the optimization for a transaction that contain no objects.
(It seemed like a bizarre case anyway).  The optimization made it
impossible to guarantee that a storage lock was acquired at the right
time.


=== ZODB3/ZODB/Connection.py 1.76.4.1 => 1.76.4.1.2.1 ===
--- ZODB3/ZODB/Connection.py:1.76.4.1	Fri Oct  4 20:28:13 2002
+++ ZODB3/ZODB/Connection.py	Fri Nov  1 14:29:21 2002
@@ -191,6 +191,10 @@
             return obj
         return self[oid]
 
+    def sortKey(self):
+        # XXX will raise an exception if the DB hasn't been set
+        return self._storage.sortKey()
+
     def _setDB(self, odb):
         """Begin a new transaction.
 
@@ -268,27 +272,8 @@
         self.__onCommitActions.append((method_name, args, kw))
         get_transaction().register(self)
 
-    # NB: commit() is responsible for calling tpc_begin() on the storage.
-    # It uses self._begun to track whether it has been called.  When
-    # self._begun is 0, it has not been called.
-
-    # This arrangement allows us to handle the special case of a
-    # transaction with no modified objects.  It is possible for
-    # registration to be occur unintentionally and for a persistent
-    # object to compensate by making itself as unchanged.  When this
-    # happens, it's possible to commit a transaction with no modified
-    # objects.
-
-    # Since tpc_begin() may raise a ReadOnlyError, don't call it if there
-    # are no objects.  This avoids spurious (?) errors when working with
-    # a read-only storage.
-
     def commit(self, object, transaction):
         if object is self:
-            if not self._begun:
-                self._storage.tpc_begin(transaction)
-                self._begun = 1
-
             # We registered ourself.  Execute a commit action, if any.
             if self.__onCommitActions is not None:
                 method_name, args, kw = self.__onCommitActions.pop(0)
@@ -313,10 +298,6 @@
             # Nothing to do
             return
 
-        if not self._begun:
-            self._storage.tpc_begin(transaction)
-            self._begun = 1
-
         stack = [object]
 
         # Create a special persistent_id that passes T and the subobject
@@ -623,7 +604,6 @@
     def tpc_begin(self, transaction, sub=None):
         self._invalidating = []
         self._creating = []
-        self._begun = 0
 
         if sub:
             # Sub-transaction!
@@ -633,10 +613,7 @@
                 self._storage = _tmp
                 _tmp.registerDB(self._db, 0)
 
-            # It's okay to always call tpc_begin() for a sub-transaction
-            # because this isn't the real storage.
-            self._storage.tpc_begin(transaction)
-            self._begun = 1
+        self._storage.tpc_begin(transaction)
 
     def tpc_vote(self, transaction):
         if self.__onCommitActions is not None: