[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