[Checkins] SVN: ZODB/branches/3.8/ Bug Fixed:

Jim Fulton jim at zope.com
Tue Dec 15 11:11:26 EST 2009


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()



More information about the checkins mailing list