SVN: ZODB/trunk/src/ Merged zagy-lp509801 branch.

Jim Fulton <[email protected]>
Newsgroups gmane.comp.python.zope.zodb.cvs
Message-ID <20100711122755.1C669941C9__32069.9681913995$1278851280$gmane$org@cvs.zope.org>
Log message for revision 114586:
  Merged zagy-lp509801 branch.
  
  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/trunk/src/CHANGES.txt
  U   ZODB/trunk/src/ZODB/Connection.py
  U   ZODB/trunk/src/ZODB/tests/testblob.py

-=-
Modified: ZODB/trunk/src/CHANGES.txt
===================================================================
--- ZODB/trunk/src/CHANGES.txt	2010-07-11 12:18:52 UTC (rev 114585)
+++ ZODB/trunk/src/CHANGES.txt	2010-07-11 12:27:54 UTC (rev 114586)
@@ -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.)
+
 - When a demo storage push method was used to create a new demo
   storage and the new storage was closed, the original was
   (incorrectly) closed.

Modified: ZODB/trunk/src/ZODB/Connection.py
===================================================================
--- ZODB/trunk/src/ZODB/Connection.py	2010-07-11 12:18:52 UTC (rev 114585)
+++ ZODB/trunk/src/ZODB/Connection.py	2010-07-11 12:27:54 UTC (rev 114586)
@@ -328,13 +328,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))
 
@@ -1121,7 +1121,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/trunk/src/ZODB/tests/testblob.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testblob.py	2010-07-11 12:18:52 UTC (rev 114585)
+++ ZODB/trunk/src/ZODB/tests/testblob.py	2010-07-11 12:27:54 UTC (rev 114586)
@@ -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.