[Zodb-checkins] SVN: ZODB/branches/3.4/ TmpStore needs to delegate
loadBefore().
Tim Peters
tim.one at comcast.net
Thu Jun 16 18:56:47 EDT 2005
Log message for revision 30825:
TmpStore needs to delegate loadBefore().
Changed:
U ZODB/branches/3.4/NEWS.txt
U ZODB/branches/3.4/src/ZODB/Connection.py
U ZODB/branches/3.4/src/ZODB/tests/testmvcc.py
-=-
Modified: ZODB/branches/3.4/NEWS.txt
===================================================================
--- ZODB/branches/3.4/NEWS.txt 2005-06-16 21:51:34 UTC (rev 30824)
+++ ZODB/branches/3.4/NEWS.txt 2005-06-16 22:56:47 UTC (rev 30825)
@@ -4,6 +4,17 @@
-3.4.1a1 DD-MMM-2005
+Savepoints
+----------
+
+- (3.4.1a1) When a savepoint is made, the states of objects modified so far
+ are saved to a temporary storage (an instance of class ``TmpStore``,
+ although that's an internal implementation detail). That storage needs
+ to implement the full storage API too, but was missing the ``loadBefore()``
+ method needed for MVCC to retrieve non-current revisions of objects. This
+ could cause spurious errors if a transaction with a pending savepoint
+ needed to fetch an older revision of some object.
+
FileStorage.UndoSearch
----------------------
Modified: ZODB/branches/3.4/src/ZODB/Connection.py
===================================================================
--- ZODB/branches/3.4/src/ZODB/Connection.py 2005-06-16 21:51:34 UTC (rev 30824)
+++ ZODB/branches/3.4/src/ZODB/Connection.py 2005-06-16 22:56:47 UTC (rev 30825)
@@ -1115,7 +1115,7 @@
self._storage = storage
for method in (
'getName', 'new_oid', 'modifiedInVersion', 'getSize',
- 'undoLog', 'versionEmpty', 'sortKey',
+ 'undoLog', 'versionEmpty', 'sortKey', 'loadBefore',
):
setattr(self, method, getattr(storage, method))
Modified: ZODB/branches/3.4/src/ZODB/tests/testmvcc.py
===================================================================
--- ZODB/branches/3.4/src/ZODB/tests/testmvcc.py 2005-06-16 21:51:34 UTC (rev 30824)
+++ ZODB/branches/3.4/src/ZODB/tests/testmvcc.py 2005-06-16 22:56:47 UTC (rev 30825)
@@ -244,8 +244,64 @@
>>> r1["b"]._p_state # GHOST
-1
->>> cn1._transaction = None # See the Cleanup section below
+Interaction with Savepoints
+---------------------------
+
+Basically, making a savepoint shouldn't have any effect on what a thread
+sees. Before ZODB 3.4.1, the internal TmpStore used when savepoints are
+pending didn't delegate all the methods necessary to make this work, so
+we'll do a quick test of that here. First get a clean slate:
+
+>>> cn1.close(); cn2.close()
+>>> cn1 = db.open(transaction_manager=tm1)
+>>> r1 = cn1.root()
+>>> r1["a"].value = 0
+>>> r1["b"].value = 1
+>>> tm1.commit()
+
+Now modify "a", but not "b", and make a savepoint.
+
+>>> r1["a"].value = 42
+>>> sp = cn1.savepoint()
+
+Over in the other connection, modify "b" and commit it. This makes the
+first connection's state for b "old".
+
+>>> cn2 = db.open(transaction_manager=tm2)
+>>> r2 = cn2.root()
+>>> r2["a"].value, r2["b"].value # shouldn't see the change to "a"
+(0, 1)
+>>> r2["b"].value = 43
+>>> tm2.commit()
+>>> r2["a"].value, r2["b"].value
+(0, 43)
+
+Now deactivate "b" in the first connection, and (re)fetch it. The first
+connection should still see 1, due to MVCC, but to get this old state
+TmpStore needs to handle the loadBefore() method.
+
+>>> r1["b"]._p_deactivate()
+
+Before 3.4.1, the next line died with
+ AttributeError: TmpStore instance has no attribute 'loadBefore'
+
+>>> r1["b"]._p_state # ghost
+-1
+>>> r1["b"].value
+1
+
+Just for fun, finish the commit and make sure both connections see the
+same things now.
+
+>>> tm1.commit()
+>>> cn1.sync(); cn2.sync()
+>>> r1["a"].value, r1["b"].value
+(42, 43)
+>>> r2["a"].value, r2["b"].value
+(42, 43)
+
+
Late invalidation
-----------------
More information about the Zodb-checkins
mailing list