[Zodb-checkins] SVN: ZODB/trunk/src/ Bug Fixed

Jim Fulton jim at zope.com
Tue Oct 26 13:51:40 EDT 2010


Log message for revision 117924:
  Bug Fixed
    When a transaction rolled back a savepoint after adding objects and
    subsequently added more objects and committed, an error could be
    raised "ValueError: A different object already has the same oid"
    causing the transaction to fail. Worse, this could leave a database
    in a state where subsequent transactions in the same process would
    fail.
  
  https://bugs.launchpad.net/zodb/+bug/665452
  

Changed:
  U   ZODB/trunk/src/CHANGES.txt
  U   ZODB/trunk/src/ZODB/Connection.py
  U   ZODB/trunk/src/ZODB/tests/testConnectionSavepoint.py

-=-
Modified: ZODB/trunk/src/CHANGES.txt
===================================================================
--- ZODB/trunk/src/CHANGES.txt	2010-10-26 15:32:22 UTC (rev 117923)
+++ ZODB/trunk/src/CHANGES.txt	2010-10-26 17:51:40 UTC (rev 117924)
@@ -2,6 +2,21 @@
  Change History
 ================
 
+3.10.1 (2010-10-??)
+===================
+
+Bugs Fixed
+----------
+
+- When a transaction rolled back a savepoint after adding objects and
+  subsequently added more objects and committed, an error could be
+  raised "ValueError: A different object already has the same oid"
+  causing the transaction to fail. Worse, this could leave a database
+  in a state where subsequent transactions in the same process would
+  fail.
+
+  https://bugs.launchpad.net/zodb/+bug/665452
+
 3.10.0 (2010-10-08)
 ===================
 

Modified: ZODB/trunk/src/ZODB/Connection.py
===================================================================
--- ZODB/trunk/src/ZODB/Connection.py	2010-10-26 15:32:22 UTC (rev 117923)
+++ ZODB/trunk/src/ZODB/Connection.py	2010-10-26 17:51:40 UTC (rev 117924)
@@ -757,6 +757,7 @@
         """Disown any objects newly saved in an uncommitted transaction."""
         if creating is None:
             creating = self._creating
+            self._creating = {}
 
         for oid in creating:
             self._db.save_oid(oid)
@@ -768,7 +769,6 @@
                 del o._p_jar
                 del o._p_oid
 
-        creating.clear()
 
     def tpc_vote(self, transaction):
         """Verify that a data manager can commit the transaction."""
@@ -1140,7 +1140,10 @@
         self._abort()
         self._registered_objects = []
         src = self._storage
-        self._invalidate_creating(src.creating)
+
+        # Invalidate objects created *after* the savepoint.
+        self._invalidate_creating((oid for oid in src.creating
+                                   if oid not in state[2]))
         index = src.index
         src.reset(*state)
         self._cache.invalidate(index)

Modified: ZODB/trunk/src/ZODB/tests/testConnectionSavepoint.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testConnectionSavepoint.py	2010-10-26 15:32:22 UTC (rev 117923)
+++ ZODB/trunk/src/ZODB/tests/testConnectionSavepoint.py	2010-10-26 17:51:40 UTC (rev 117924)
@@ -230,6 +230,40 @@
     >>> transaction.abort()
     """
 
+def testNewOidNotReusedAfterRollbackOfPostAddSavepoint():
+    """\
+    >>> connection = ZODB.connection(None)
+    >>> root = connection.root()
+
+    Add an item, and make a savepoint.
+
+    >>> root['p'] = p = ZODB.tests.util.P()
+    >>> sp = transaction.savepoint()
+
+    Now rollback the savepoint.
+
+    >>> sp.rollback()
+
+    At this point, the item still exists, since it was created before
+    the savepoint we rolled back.
+
+    >>> root['p']._p_oid
+    '\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01'
+
+    Add another item, and make another savepoint.
+
+    >>> root['p2'] = p2 = ZODB.tests.util.P()
+    >>> sp2 = transaction.savepoint()
+
+    The second item should not reuse the oid of the first.
+
+    >>> p2._p_oid
+    '\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02'
+
+    transaction.abort()
+    """
+
+
 def tearDown(test):
     transaction.abort()
 



More information about the Zodb-checkins mailing list