[Zodb-checkins] SVN: ZODB/trunk/ Merge rev 30825 from 3.4 branch.

Tim Peters tim.one at comcast.net
Thu Jun 16 19:48:56 EDT 2005


Log message for revision 30826:
  Merge rev 30825 from 3.4 branch.
  
  TmpStore needs to delegate loadBefore().
  

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

-=-
Modified: ZODB/trunk/NEWS.txt
===================================================================
--- ZODB/trunk/NEWS.txt	2005-06-16 22:56:47 UTC (rev 30825)
+++ ZODB/trunk/NEWS.txt	2005-06-16 23:48:56 UTC (rev 30826)
@@ -1,13 +1,25 @@
-What's new in ZODB3 3.5a2?
+What's new in ZODB3 3.5a3?
 ==========================
-Release date: 16-Jun-2005
+Release date: DD-MMM-2005
 
 Following is combined news from "internal releases" (to support ongoing
 Zope3 development).  These are the dates of the internal releases:
 
-- 3.5a2 DD-MMM-2005
+- 3.5a3 DD-MMM-2005
+- 3.5a2 16-Jun-2005
 - 3.5a1 10-Jun-2005
 
+Savepoints
+----------
+
+- (3.5a3) 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.
+
 Multi-database
 --------------
 
@@ -31,6 +43,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/trunk/src/ZODB/Connection.py
===================================================================
--- ZODB/trunk/src/ZODB/Connection.py	2005-06-16 22:56:47 UTC (rev 30825)
+++ ZODB/trunk/src/ZODB/Connection.py	2005-06-16 23:48:56 UTC (rev 30826)
@@ -1120,7 +1120,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/trunk/src/ZODB/tests/testmvcc.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testmvcc.py	2005-06-16 22:56:47 UTC (rev 30825)
+++ ZODB/trunk/src/ZODB/tests/testmvcc.py	2005-06-16 23:48:56 UTC (rev 30826)
@@ -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