[Zope-Checkins] CVS: Zope/lib/python/ZODB - Connection.py:1.86.2.1

Shane Hathaway shane@zope.com
Tue, 11 Feb 2003 13:53:08 -0500


Update of /cvs-repository/Zope/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv8010

Modified Files:
      Tag: shane-conflict-handling-branch
	Connection.py 
Log Message:
Fixed the conflicting commit bug.  Now, if a read conflict occurs, the
application is not allowed to commit other data.  This should make greedy
exception handlers less dangerous.

Also had to correct the test slightly: apparently, failed attempts to
commit result in an implicit transaction abort.  This test
needed to be aware of that.


=== Zope/lib/python/ZODB/Connection.py 1.86 => 1.86.2.1 ===
--- Zope/lib/python/ZODB/Connection.py:1.86	Thu Feb  6 15:32:18 2003
+++ Zope/lib/python/ZODB/Connection.py	Tue Feb 11 13:52:36 2003
@@ -56,6 +56,7 @@
     _opened=None
     _code_timestamp = 0
     _transaction = None
+    _conflicting = None  # If there are conflicts, contains a list of OIDs.
 
     # Experimental. Other connections can register to be closed
     # when we close by putting something here.
@@ -215,6 +216,7 @@
         self._storage=s=odb._storage
         self._sortKey = odb._storage.sortKey
         self.new_oid=s.new_oid
+        self._conflicting = None
         if self._code_timestamp != global_code_timestamp:
             # New code is in place.  Start a new cache.
             self._resetCache()
@@ -274,6 +276,7 @@
             self.__onCloseCallbacks = None
         self._db=self._storage=self._tmp=self.new_oid=self._opened=None
         self._debug_info=()
+        self._conflicting = None
         # Return the connection to the pool.
         db._closeConnection(self)
 
@@ -562,6 +565,9 @@
                     raise ConflictError(object=object)
 
         except ConflictError:
+            if self._conflicting is None:
+                self._conflicting = []
+            self._conflicting.append(oid)
             raise
         except:
             LOG('ZODB',ERROR, "Couldn't load state for %s" % `oid`,
@@ -612,6 +618,7 @@
         if self.__onCommitActions is not None:
             del self.__onCommitActions
         self._storage.tpc_abort(transaction)
+        self._conflicting = None
         self._cache.invalidate(self._invalidated)
         self._cache.invalidate(self._invalidating)
         self._invalidate_creating()
@@ -630,6 +637,9 @@
         self._storage.tpc_begin(transaction)
 
     def tpc_vote(self, transaction):
+        if self._conflicting is not None:
+            raise ConflictError('Conflicts on OIDs %s' %
+                                repr(self._conflicting))
         if self.__onCommitActions is not None:
             del self.__onCommitActions
         try: