[Zodb-checkins] SVN: ZODB/trunk/ Forward port from Zope 2.7 branch.

Tim Peters tim.one at comcast.net
Tue Aug 31 19:48:08 EDT 2004


Log message for revision 27375:
  Forward port from Zope 2.7 branch.
  
  _handle_independent():  Failed to record that a ReadConflictError
  was raised for an object with a _p_independent() method that
  returned false.
  


Changed:
  U   ZODB/trunk/NEWS.txt
  U   ZODB/trunk/src/ZODB/Connection.py
  U   ZODB/trunk/src/ZODB/tests/testZODB.py


-=-
Modified: ZODB/trunk/NEWS.txt
===================================================================
--- ZODB/trunk/NEWS.txt	2004-08-31 23:26:21 UTC (rev 27374)
+++ ZODB/trunk/NEWS.txt	2004-08-31 23:48:08 UTC (rev 27375)
@@ -43,6 +43,12 @@
 transaction
 -----------
 
+If ReadConflictError was raised by an attempt to load an object with a
+_p_independent() method that returned false, attempting to commit the
+transaction failed to (re)raise ReadConflictError for that object.  Note
+that ZODB intends to prevent committing a transaction in which a
+ReadConflictError occurred; this was an obscure case it missed.
+
 Growing pains:  ZODB 3.1 and 3.2 had a bug wherein Transaction.begin()
 didn't abort the current transaction if the only pending changes were in a
 subtransaction.  In ZODB 3.3, it's intended that transaction managers be

Modified: ZODB/trunk/src/ZODB/Connection.py
===================================================================
--- ZODB/trunk/src/ZODB/Connection.py	2004-08-31 23:26:21 UTC (rev 27374)
+++ ZODB/trunk/src/ZODB/Connection.py	2004-08-31 23:48:08 UTC (rev 27375)
@@ -229,6 +229,14 @@
         self._inv_lock = threading.Lock()
         self._invalidated = d = {}
         self._invalid = d.has_key
+
+        # We intend to prevent committing a transaction in which
+        # ReadConflictError occurs.  _conflicts is the set of oids that
+        # experienced ReadConflictError.  Any time we raise ReadConflictError,
+        # the oid should be added to this set, and we should be sure that the
+        # object is registered.  Because it's registered, Connection.commit()
+        # will raise ReadConflictError again (because the oid is in
+        # _conflicts).
         self._conflicts = {}
 
         # If MVCC is enabled, then _mvcc is True and _txn_time stores
@@ -907,6 +915,7 @@
             finally:
                 self._inv_lock.release()
         else:
+            self._conflicts[obj._p_oid] = 1
             self._register(obj)
             raise ReadConflictError(object=obj)
 

Modified: ZODB/trunk/src/ZODB/tests/testZODB.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testZODB.py	2004-08-31 23:26:21 UTC (rev 27374)
+++ ZODB/trunk/src/ZODB/tests/testZODB.py	2004-08-31 23:48:08 UTC (rev 27375)
@@ -286,6 +286,10 @@
         # transaction.
         if shouldFail:
             self.assertRaises(ReadConflictError, lambda: obj.child1)
+            # And since ReadConflictError was raised, attempting to commit
+            # the transaction should re-raise it.  checkNotIndependent()
+            # failed this part of the test for a long time.
+            self.assertRaises(ReadConflictError, tm2.get().commit)
         else:
             # make sure that accessing the object succeeds
             obj.child1



More information about the Zodb-checkins mailing list