Commit 9b8015f8 authored by Jim Fulton's avatar Jim Fulton

Bug Fixed

 Updating blobs in save points could cause spurious "invalidations
 out of order" errors.  https://bugs.launchpad.net/zodb/+bug/509801

(Thanks to Christian Zagrodnick for chasing this down.)
parent 39e96200
...@@ -4,6 +4,11 @@ Whats new in ZODB 3.8.6 (2010-??-??) ...@@ -4,6 +4,11 @@ Whats new in ZODB 3.8.6 (2010-??-??)
Bugs Fixed: Bugs Fixed:
- Updating blobs in save points could cause spurious "invalidations
out of order" errors. https://bugs.launchpad.net/zodb/+bug/509801
(Thanks to Christian Zagrodnick for chasing this down.)
- BTree sets and tree sets didn't correctly check values passed to - BTree sets and tree sets didn't correctly check values passed to
update or to constructors, causing Python to exit under certain update or to constructors, causing Python to exit under certain
circumstances. circumstances.
......
...@@ -332,7 +332,7 @@ class Connection(ExportImport, object): ...@@ -332,7 +332,7 @@ class Connection(ExportImport, object):
try: try:
if self._txn_time is None: if self._txn_time is None:
self._txn_time = tid self._txn_time = tid
elif tid < self._txn_time: elif (tid < self._txn_time) and (tid is not None):
raise AssertionError("invalidations out of order, %r < %r" raise AssertionError("invalidations out of order, %r < %r"
% (tid, self._txn_time)) % (tid, self._txn_time))
...@@ -346,7 +346,7 @@ class Connection(ExportImport, object): ...@@ -346,7 +346,7 @@ class Connection(ExportImport, object):
self._invalidatedCache = True self._invalidatedCache = True
finally: finally:
self._inv_lock.release() self._inv_lock.release()
def root(self): def root(self):
"""Return the database root object.""" """Return the database root object."""
...@@ -1137,7 +1137,7 @@ class Connection(ExportImport, object): ...@@ -1137,7 +1137,7 @@ class Connection(ExportImport, object):
# that that the next attribute access of its name # that that the next attribute access of its name
# unghostify it, which will cause its blob data # unghostify it, which will cause its blob data
# to be reattached "cleanly" # to be reattached "cleanly"
self.invalidate(s, {oid:True}) self.invalidate(None, (oid, ))
else: else:
s = self._storage.store(oid, serial, data, s = self._storage.store(oid, serial, data,
self._version, transaction) self._version, transaction)
......
...@@ -539,6 +539,44 @@ def loadblob_tmpstore(): ...@@ -539,6 +539,44 @@ def loadblob_tmpstore():
>>> os.unlink(storagefile+".tmp") >>> os.unlink(storagefile+".tmp")
""" """
def savepoint_commits_without_invalidations_out_of_order():
"""Make sure transactions with blobs can be commited without the
invalidations out of order error (LP #509801)
>>> from ZODB.MappingStorage import MappingStorage
>>> from ZODB.blob import BlobStorage
>>> from ZODB.DB import DB
>>> from ZODB.serialize import referencesf
>>> from tempfile import mkdtemp
>>> base_storage = MappingStorage("test")
>>> blob_dir = mkdtemp()
>>> blob_storage = BlobStorage(blob_dir, base_storage)
>>> db = DB(blob_storage)
>>> tm1 = transaction.TransactionManager()
>>> conn1 = db.open(transaction_manager=tm1)
>>> conn1.root()['b'] = ZODB.blob.Blob()
>>> conn1.root()['b'].open('w').write('initial')
>>> tm1.commit()
>>> conn1.root()['b'].open('w').write('1')
>>> _ = tm1.savepoint()
>>> tm2 = transaction.TransactionManager()
>>> conn2 = db.open(transaction_manager=tm2)
>>> conn2.root()['b'].open('w').write('2')
>>> _ = tm1.savepoint()
>>> conn1.root()['b'].open().read()
'1'
>>> conn2.root()['b'].open().read()
'2'
>>> tm2.commit()
>>> tm1.commit() # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
ConflictError: database conflict error...
>>> db.close()
"""
def setUp(test): def setUp(test):
ZODB.tests.util.setUp(test) ZODB.tests.util.setUp(test)
def rmtree(path): def rmtree(path):
......
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