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

Jim Fulton jim at zope.com
Mon Sep 20 14:16:36 EDT 2010


Log message for revision 116675:
  Bug Fixed:
  - Conflict errors didn't invalidate ZEO cache entries.
  

Changed:
  U   ZODB/branches/3.9/src/CHANGES.txt
  U   ZODB/branches/3.9/src/ZEO/ClientStorage.py
  U   ZODB/branches/3.9/src/ZEO/tests/testZEO.py

-=-
Modified: ZODB/branches/3.9/src/CHANGES.txt
===================================================================
--- ZODB/branches/3.9/src/CHANGES.txt	2010-09-20 18:09:40 UTC (rev 116674)
+++ ZODB/branches/3.9/src/CHANGES.txt	2010-09-20 18:16:35 UTC (rev 116675)
@@ -25,6 +25,8 @@
   invalidation transaction ids matched the cached transaction ids
   should have been ignored.
 
+- Conflict errors didn't invalidate ZEO cache entries.
+
 - 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/ZEO/ClientStorage.py
===================================================================
--- ZODB/branches/3.9/src/ZEO/ClientStorage.py	2010-09-20 18:09:40 UTC (rev 116674)
+++ ZODB/branches/3.9/src/ZEO/ClientStorage.py	2010-09-20 18:16:35 UTC (rev 116675)
@@ -902,6 +902,7 @@
             del self._serials[:l]
             for oid, s in r:
                 if isinstance(s, Exception):
+                    self._cache.invalidate(oid, None)
                     raise s
                 self._seriald[oid] = s
             return r

Modified: ZODB/branches/3.9/src/ZEO/tests/testZEO.py
===================================================================
--- ZODB/branches/3.9/src/ZEO/tests/testZEO.py	2010-09-20 18:09:40 UTC (rev 116674)
+++ ZODB/branches/3.9/src/ZEO/tests/testZEO.py	2010-09-20 18:16:35 UTC (rev 116675)
@@ -24,7 +24,7 @@
      MTStorage, ReadOnlyStorage, IteratorStorage, RecoveryStorage
 from ZODB.tests.MinPO import MinPO
 from ZODB.tests.StorageTestBase import zodb_unpickle
-
+from ZODB.utils import p64, u64
 import asyncore
 import doctest
 import logging
@@ -1227,6 +1227,78 @@
     testing exit immediately
     """
 
+def invalidate_client_cache_entry_on_server_commit_error():
+    """
+
+When the serials returned during commit includes an error, typically a
+conflict error, invalidate the cache entry.  This is important when
+the cache is messed up.
+
+    >>> addr, _ = start_server()
+    >>> conn1 = ZEO.connection(addr)
+    >>> conn1.root.x = conn1.root().__class__()
+    >>> transaction.commit()
+    >>> conn1.root.x
+    {}
+
+    >>> cs = ZEO.ClientStorage.ClientStorage(addr, client='cache')
+    >>> conn2 = ZODB.connection(cs)
+    >>> conn2.root.x
+    {}
+
+    >>> conn2.close()
+    >>> cs.close()
+
+    >>> conn1.root.x['x'] = 1
+    >>> transaction.commit()
+    >>> conn1.root.x
+    {'x': 1}
+
+Now, let's screw up the cache by making it have a last tid that is later than
+the root serial.
+
+    >>> import ZEO.cache
+    >>> cache = ZEO.cache.ClientCache('cache-1.zec')
+    >>> cache.setLastTid(p64(u64(conn1.root.x._p_serial)+1))
+    >>> cache.close()
+
+We'll also update the server so that it's last tid is newer than the cache's:
+
+    >>> conn1.root.y = 1
+    >>> transaction.commit()
+    >>> conn1.root.y = 2
+    >>> transaction.commit()
+
+Now, if we reopen the client storage, we'll get the wrong root:
+
+    >>> cs = ZEO.ClientStorage.ClientStorage(addr, client='cache')
+    >>> conn2 = ZODB.connection(cs)
+    >>> conn2.root.x
+    {}
+
+And, we'll get a conflict error if we try to modify it:
+
+    >>> conn2.root.x['y'] = 1
+    >>> transaction.commit() # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    ...
+    ConflictError: ...
+
+But, if we abort, we'll get up to date data and we'll see the changes.
+
+    >>> transaction.abort()
+    >>> conn2.root.x
+    {'x': 1}
+    >>> conn2.root.x['y'] = 1
+    >>> transaction.commit()
+    >>> sorted(conn2.root.x.items())
+    [('x', 1), ('y', 1)]
+
+    >>> cs.close()
+    >>> conn1.close()
+
+    """
+
 def quick_close_doesnt_kill_server():
     r"""
 



More information about the Zodb-checkins mailing list