[Zodb-checkins] CVS: Packages/ZODB/tests - testZODB.py:1.15.8.9
Tim Peters
tim.one at comcast.net
Mon May 2 16:30:27 EDT 2005
Update of /cvs-repository/Packages/ZODB/tests
In directory cvs.zope.org:/tmp/cvs-serv26821/ZODB/tests
Modified Files:
Tag: Zope-2_7-branch
testZODB.py
Log Message:
tpc_finish: Repair longstanding bugs in subtransaction commit.
Jim (Fulton) discovered this in ZODB 3.4's code, while implementing
savepoint/rollback. Same bugs have been there at least since ZODB 3.1.
=== Packages/ZODB/tests/testZODB.py 1.15.8.8 => 1.15.8.9 ===
--- Packages/ZODB/tests/testZODB.py:1.15.8.8 Thu Sep 16 20:42:01 2004
+++ Packages/ZODB/tests/testZODB.py Mon May 2 16:30:27 2005
@@ -468,5 +468,69 @@
self.assertEqual(cn.root()['a'], 100)
cn.close()
+ def checkSubtxnCommitDoesntGetInvalidations(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.
+
+ # Set up the database, to hold
+ # root --> "p" -> value = 1
+ # --> "q" -> value = 2
+ conn = self._db.open()
+ conn.setLocalTransaction()
+ r1 = conn.root()
+ p = P()
+ p.value = 1
+ r1["p"] = p
+ q = P()
+ q.value = 2
+ r1["q"] = q
+ conn.getTransaction().commit()
+
+ # Now txn T1 changes p.value to 3 locally (subtxn commit).
+ p.value = 3
+ conn.getTransaction().commit(True)
+
+ # Start new txn T2 with a new connection.
+ cn2 = self._db.open()
+ cn2.setLocalTransaction()
+ 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
+ cn2.getTransaction().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 do another subtxn commit in T1. This shouldn't change what
+ # T1 sees for p and q.
+ rt["r"] = P()
+ conn.getTransaction().commit(True)
+
+ # Doing that subtxn commit in T1 should not process invalidations
+ # from T2's commit. p.value should still be 3 here (because that's
+ # what T1 subtxn-committed 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:
+ conn.getTransaction().abort()
+
def test_suite():
return unittest.makeSuite(ZODBTests, 'check')
More information about the Zodb-checkins
mailing list