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-??-??)
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
update or to constructors, causing Python to exit under certain
circumstances.
......
......@@ -332,7 +332,7 @@ class Connection(ExportImport, object):
try:
if self._txn_time is None:
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"
% (tid, self._txn_time))
......@@ -346,7 +346,7 @@ class Connection(ExportImport, object):
self._invalidatedCache = True
finally:
self._inv_lock.release()
def root(self):
"""Return the database root object."""
......@@ -1137,7 +1137,7 @@ class Connection(ExportImport, object):
# that that the next attribute access of its name
# unghostify it, which will cause its blob data
# to be reattached "cleanly"
self.invalidate(s, {oid:True})
self.invalidate(None, (oid, ))
else:
s = self._storage.store(oid, serial, data,
self._version, transaction)
......
......@@ -539,6 +539,44 @@ def loadblob_tmpstore():
>>> 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):
ZODB.tests.util.setUp(test)
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