Commit 70b7e721 authored by Jim Fulton's avatar Jim Fulton

Fixed a bug in processing invalidations. Cache last tid shouldn't be set until...

Fixed a bug in processing invalidations. Cache last tid shouldn't be set until all of the invalidations have been processed. For this reason, we no longer set the last tid in the cache invalidate method
parent b209919c
......@@ -8,6 +8,9 @@
Bugs fixed
----------
- Process exits or database closes could cause ZEO caches to have
incorrect data due to a problem in the way invalidations were processed.
- Database connections didn't invalidate cache entries when conflict
errors were raised in response to checkCurrentSerialInTransaction
errors. Normally, this shouldn't be a problem, since there should be
......
......@@ -1213,7 +1213,7 @@ class ClientStorage(object):
return
for oid, _ in self._seriald.iteritems():
self._cache.invalidate(oid, tid, False)
self._cache.invalidate(oid, tid)
for oid, data in self._tbuf:
# If data is None, we just invalidate.
......@@ -1224,7 +1224,7 @@ class ClientStorage(object):
self._cache.store(oid, s, None, data)
else:
# object deletion
self._cache.invalidate(oid, tid, False)
self._cache.invalidate(oid, tid)
if self.fshelper is not None:
blobs = self._tbuf.blobs
......@@ -1479,6 +1479,7 @@ class ClientStorage(object):
if oid == self._load_oid:
self._load_status = 0
self._cache.invalidate(oid, tid)
self._cache.setLastTid(tid)
if self._db is not None:
self._db.invalidate(tid, oids)
......
......@@ -664,20 +664,13 @@ class ClientCache(object):
# - oid object id
# - tid the id of the transaction that wrote a new revision of oid,
# or None to forget all cached info about oid.
# - server_invalidation, a flag indicating whether the
# invalidation has come from the server. It's possible, due
# to threading issues, that when applying a local
# invalidation after a store, that later invalidations from
# the server may already have arrived.
@locked
def invalidate(self, oid, tid, server_invalidation=True):
def invalidate(self, oid, tid):
ofs = self.current.get(oid)
if ofs is None:
# 0x10 == invalidate (miss)
self._trace(0x10, oid, tid)
if server_invalidation:
self.setLastTid(tid)
return
self.f.seek(ofs)
......@@ -704,9 +697,6 @@ class ClientCache(object):
# 0x1C = invalidate (hit, saving non-current)
self._trace(0x1C, oid, tid)
if server_invalidation:
self.setLastTid(tid)
##
# Generates (oid, serial) oairs for all objects in the
# cache. This generator is used by cache verification.
......
......@@ -83,9 +83,11 @@ class CacheTests(ZODB.tests.util.TestCase):
self.cache.setLastTid(n2)
self.assertEqual(self.cache.getLastTid(), n2)
self.assertEqual(self.cache.getLastTid(), n2)
self.cache.invalidate(n1, n3)
self.cache.setLastTid(n3)
self.assertEqual(self.cache.getLastTid(), n3)
# Check that setting tids out of order gives an error:
# the cache complains only when it's non-empty
self.cache.store(n1, n3, None, 'x')
self.assertRaises(ValueError, self.cache.setLastTid, n2)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment