[Zodb-checkins]
SVN: ZODB/branches/tim-deprecate-subtxn/src/ZODB/tests/testZODB.py
New test checkSavepointDoesntGetInvalidations(), to
Tim Peters
tim.one at comcast.net
Wed Jul 13 21:22:59 EDT 2005
Log message for revision 33309:
New test checkSavepointDoesntGetInvalidations(), to
verify that a old subtxn bug didn't reappear in savepoints.
Changed:
U ZODB/branches/tim-deprecate-subtxn/src/ZODB/tests/testZODB.py
-=-
Modified: ZODB/branches/tim-deprecate-subtxn/src/ZODB/tests/testZODB.py
===================================================================
--- ZODB/branches/tim-deprecate-subtxn/src/ZODB/tests/testZODB.py 2005-07-13 22:53:27 UTC (rev 33308)
+++ ZODB/branches/tim-deprecate-subtxn/src/ZODB/tests/testZODB.py 2005-07-14 01:22:58 UTC (rev 33309)
@@ -437,6 +437,72 @@
finally:
tm1.abort()
+ def checkSavepointDoesntGetInvalidations(self):
+ # Prior to ZODB 3.2.9 and 3.4, Connection.tpc_finish() processed
+ # invalidations even for a subtxn commit. This could make
+ # inconsistent state visible after a subtxn commit. There was a
+ # suspicion that POSKeyError was possible as a result, but I wasn't
+ # able to construct a case where that happened.
+ # Subtxns are deprecated now, but it's good to check that the
+ # same kind of thing doesn't happen when making savepoints either.
+
+ # Set up the database, to hold
+ # root --> "p" -> value = 1
+ # --> "q" -> value = 2
+ tm1 = transaction.TransactionManager()
+ conn = self._db.open(transaction_manager=tm1)
+ r1 = conn.root()
+ p = P()
+ p.value = 1
+ r1["p"] = p
+ q = P()
+ q.value = 2
+ r1["q"] = q
+ tm1.commit()
+
+ # Now txn T1 changes p.value to 3 locally (subtxn commit).
+ p.value = 3
+ tm1.savepoint()
+
+ # Start new txn T2 with a new connection.
+ tm2 = transaction.TransactionManager()
+ cn2 = self._db.open(transaction_manager=tm2)
+ r2 = cn2.root()
+ p2 = r2["p"]
+ self.assertEqual(p._p_oid, p2._p_oid)
+ # T2 shouldn't see T1's change of p.value to 3, because T1 didn't
+ # commit yet.
+ self.assertEqual(p2.value, 1)
+ # Change p.value to 4, and q.value to 5. Neither should be visible
+ # to T1, because T1 is still in progress.
+ p2.value = 4
+ q2 = r2["q"]
+ self.assertEqual(q._p_oid, q2._p_oid)
+ self.assertEqual(q2.value, 2)
+ q2.value = 5
+ tm2.commit()
+
+ # Back to T1. p and q still have the expected values.
+ rt = conn.root()
+ self.assertEqual(rt["p"].value, 3)
+ self.assertEqual(rt["q"].value, 2)
+
+ # Now make another savepoint in T1. This shouldn't change what
+ # T1 sees for p and q.
+ rt["r"] = P()
+ tm1.savepoint()
+
+ # Making that savepoint in T1 should not process invalidations
+ # from T2's commit. p.value should still be 3 here (because that's
+ # what T1 savepointed earlier), and q.value should still be 2.
+ # Prior to ZODB 3.2.9 and 3.4, q.value was 5 here.
+ rt = conn.root()
+ try:
+ self.assertEqual(rt["p"].value, 3)
+ self.assertEqual(rt["q"].value, 2)
+ finally:
+ tm1.abort()
+
def checkReadConflictErrorClearedDuringAbort(self):
# When a transaction is aborted, the "memory" of which
# objects were the cause of a ReadConflictError during
More information about the Zodb-checkins
mailing list