SVN: ZODB/branches/3.8/ Bug Fixed:

Jim Fulton <[email protected]>
Newsgroups gmane.comp.python.zope.zodb.cvs
Message-ID <[email protected]>
Log message for revision 106543:
  Bug Fixed:
  
  - A ZEO threading bug could cause transactions to read inconsistent
    data.  (This sometimes caused an AssertionError in
    Connection._setstate_noncurrent.)
  

Changed:
  U   ZODB/branches/3.8/NEWS.txt
  U   ZODB/branches/3.8/src/ZEO/ClientStorage.py
  U   ZODB/branches/3.8/src/ZODB/Connection.py

-=-
Modified: ZODB/branches/3.8/NEWS.txt
===================================================================
--- ZODB/branches/3.8/NEWS.txt	2009-12-15 16:08:42 UTC (rev 106542)
+++ ZODB/branches/3.8/NEWS.txt	2009-12-15 16:11:25 UTC (rev 106543)
@@ -1,3 +1,12 @@
+Whats new in ZODB 3.8.5 (2009-12-16)
+====================================
+
+Bugs Fixed:
+
+- A ZEO threading bug could cause transactions to read inconsistent
+  data.  (This sometimes caused an AssertionError in
+  Connection._setstate_noncurrent.)
+
 Whats new in ZODB 3.8.4 (2009-10-01)
 ====================================
 

Modified: ZODB/branches/3.8/src/ZEO/ClientStorage.py
===================================================================
--- ZODB/branches/3.8/src/ZEO/ClientStorage.py	2009-12-15 16:08:42 UTC (rev 106542)
+++ ZODB/branches/3.8/src/ZEO/ClientStorage.py	2009-12-15 16:11:25 UTC (rev 106543)
@@ -1079,15 +1079,12 @@
                 raise ClientDisconnected(
                        'Calling tpc_finish() on a disconnected transaction')
 
-            # The calls to tpc_finish() and _update_cache() should
-            # never run currently with another thread, because the
-            # tpc_cond condition variable prevents more than one
-            # thread from calling tpc_finish() at a time.
-            tid = self._server.tpc_finish(id(txn))
-
+            finished = 0
             try:
                 self._lock.acquire()  # for atomic processing of invalidations
                 try:
+                    tid = self._server.tpc_finish(id(txn))
+                    finished = 1
                     self._update_cache(tid)
                     if f is not None:
                         f(tid)
@@ -1097,9 +1094,10 @@
                 r = self._check_serials()
                 assert r is None or len(r) == 0, "unhandled serialnos: %s" % r
             except:
-                # The server successfully committed.  If we get a failure
-                # here, our own state will be in question, so reconnect.
-                self._connection.close()
+                if finished:
+                    # The server successfully committed.  If we get a failure
+                    # here, our own state will be in question, so reconnect.
+                    self._connection.close()
                 raise
 
             self.end_transaction()

Modified: ZODB/branches/3.8/src/ZODB/Connection.py
===================================================================
--- ZODB/branches/3.8/src/ZODB/Connection.py	2009-12-15 16:08:42 UTC (rev 106542)
+++ ZODB/branches/3.8/src/ZODB/Connection.py	2009-12-15 16:11:25 UTC (rev 106543)
@@ -332,6 +332,10 @@
         try:
             if self._txn_time is None:
                 self._txn_time = tid
+            elif tid < self._txn_time:
+                raise AssertionError("invalidations out of order, %r < %r"
+                                     % (tid, self._txn_time))
+
             self._invalidated.update(oids)
         finally:
             self._inv_lock.release()
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.