SVN: ZODB/branches/3.9/src/ Bug Fixed

Jim Fulton <[email protected]>
Newsgroups gmane.comp.python.zope.zodb.cvs
Message-ID <20100920172237.8E19C80270D__20126.5652351596$1285003362$gmane$org@cvs.zope.org>
Log message for revision 116670:
  Bug Fixed
  
  - Updating blobs in save points could cause spurious "invalidations
    out of order" errors.  https://bugs.launchpad.net/zodb/+bug/509801
  
  (Thanks to Christian Zagrodnick for chasing this down.)
  

Changed:
  U   ZODB/branches/3.9/src/CHANGES.txt
  U   ZODB/branches/3.9/src/ZODB/Connection.py
  U   ZODB/branches/3.9/src/ZODB/tests/testblob.py

-=-
Modified: ZODB/branches/3.9/src/CHANGES.txt
===================================================================
--- ZODB/branches/3.9/src/CHANGES.txt	2010-09-20 17:08:13 UTC (rev 116669)
+++ ZODB/branches/3.9/src/CHANGES.txt	2010-09-20 17:22:37 UTC (rev 116670)
@@ -8,6 +8,11 @@
 Bugs Fixed
 ----------
 
+- Updating blobs in save points could cause spurious "invalidations
+  out of order" errors.  https://bugs.launchpad.net/zodb/+bug/509801
+
+  (Thanks to Christian Zagrodnick for chasing this down.)
+
 - On Mac OS X, clients that connected and disconnected quickly could
   cause a ZEO server to stop accepting connections, due to a failure
   to catch errors in the initial part of the connection process.

Modified: ZODB/branches/3.9/src/ZODB/Connection.py
===================================================================
--- ZODB/branches/3.9/src/ZODB/Connection.py	2010-09-20 17:08:13 UTC (rev 116669)
+++ ZODB/branches/3.9/src/ZODB/Connection.py	2010-09-20 17:22:37 UTC (rev 116670)
@@ -335,13 +335,13 @@
     def invalidate(self, tid, oids):
         """Notify the Connection that transaction 'tid' invalidated oids."""
         if self.before is not None:
-            # this is an historical connection.  Invalidations are irrelevant.
+            # This is a historical connection.  Invalidations are irrelevant.
             return
         self._inv_lock.acquire()
         try:
             if self._txn_time is None:
                 self._txn_time = tid
-            elif tid < self._txn_time:
+            elif (tid < self._txn_time) and (tid is not None):
                 raise AssertionError("invalidations out of order, %r < %r"
                                      % (tid, self._txn_time))
 
@@ -1175,7 +1175,7 @@
                 # that that the next attribute access of its name
                 # unghostify it, which will cause its blob data
                 # to be reattached "cleanly"
-                self.invalidate(s, {oid:True})
+                self.invalidate(None, (oid, ))
             else:
                 s = self._storage.store(oid, serial, data,
                                         '', transaction)

Modified: ZODB/branches/3.9/src/ZODB/tests/testblob.py
===================================================================
--- ZODB/branches/3.9/src/ZODB/tests/testblob.py	2010-09-20 17:08:13 UTC (rev 116669)
+++ ZODB/branches/3.9/src/ZODB/tests/testblob.py	2010-09-20 17:22:37 UTC (rev 116670)
@@ -563,6 +563,35 @@
     >>> db.close()
     """
 
+def savepoint_commits_without_invalidations_out_of_order():
+    """Make sure transactions with blobs can be commited without the
+    invalidations out of order error (LP #509801)
+
+    >>> bs = create_storage()
+    >>> db = DB(bs)
+    >>> tm1 = transaction.TransactionManager()
+    >>> conn1 = db.open(transaction_manager=tm1)
+    >>> conn1.root.b = ZODB.blob.Blob('initial')
+    >>> tm1.commit()
+    >>> conn1.root.b.open('w').write('1')
+    >>> _ = tm1.savepoint()
+
+    >>> tm2 = transaction.TransactionManager()
+    >>> conn2 = db.open(transaction_manager=tm2)
+    >>> conn2.root.b.open('w').write('2')
+    >>> _ = tm1.savepoint()
+    >>> conn1.root.b.open().read()
+    '1'
+    >>> conn2.root.b.open().read()
+    '2'
+    >>> tm2.commit()
+    >>> tm1.commit()  # doctest: +IGNORE_EXCEPTION_DETAIL
+    Traceback (most recent call last):
+        ...
+    ConflictError: database conflict error...
+    >>> db.close()
+    """
+
 def savepoint_cleanup():
     """Make sure savepoint data gets cleaned up.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.