[Neo-report] r2600 vincent - in /trunk/neo: storage/ tests/storage/
nobody at svn.erp5.org
nobody at svn.erp5.org
Mon Jan 10 11:46:49 CET 2011
Author: vincent
Date: Mon Jan 10 11:46:49 2011
New Revision: 2600
Log:
Add conflict detection for multiple "undo" in same transaction.
Detect if a client requests multiple undo/store based on wrong revisions.
Also, don't try to acquire lock when we know we have it.
Modified:
trunk/neo/storage/transactions.py
trunk/neo/tests/storage/testTransactions.py
Modified: trunk/neo/storage/transactions.py
==============================================================================
--- trunk/neo/storage/transactions.py [iso-8859-1] (original)
+++ trunk/neo/storage/transactions.py [iso-8859-1] Mon Jan 10 11:46:49 2011
@@ -239,16 +239,28 @@ class TransactionManager(object):
self._app.executeQueuedEvents()
# Attemp to acquire lock again.
locking_tid = self._store_lock_dict.get(oid)
- if locking_tid == tid:
- neo.logging.info('Transaction %s storing %s more than once',
- dump(tid), dump(oid))
- elif locking_tid is None:
+ if locking_tid in (None, tid):
# check if this is generated from the latest revision.
- history_list = self._app.dm.getObjectHistory(oid)
- if history_list and history_list[0][0] != serial:
+ if locking_tid == tid:
+ # If previous store was an undo, next store must be based on
+ # undo target.
+ _, _, _, _, previous_serial = self._transaction_dict[
+ tid].getObject(oid)
+ if previous_serial is None:
+ # XXX: use some special serial when previous store was not
+ # an undo ? Maybe it should just not happen.
+ neo.logging.info('Transaction %s storing %s more than '
+ 'once', dump(tid), dump(oid))
+ else:
+ previous_serial = None
+ if previous_serial is None:
+ history_list = self._app.dm.getObjectHistory(oid)
+ if history_list:
+ previous_serial = history_list[0][0]
+ if previous_serial is not None and previous_serial != serial:
neo.logging.info('Resolvable conflict on %r:%r', dump(oid),
dump(tid))
- raise ConflictError(history_list[0][0])
+ raise ConflictError(previous_serial)
neo.logging.info('Transaction %s storing %s', dump(tid), dump(oid))
self._store_lock_dict[oid] = tid
elif locking_tid > tid:
Modified: trunk/neo/tests/storage/testTransactions.py
==============================================================================
--- trunk/neo/tests/storage/testTransactions.py [iso-8859-1] (original)
+++ trunk/neo/tests/storage/testTransactions.py [iso-8859-1] Mon Jan 10 11:46:49 2011
@@ -372,7 +372,9 @@ class TransactionManagerTests(NeoUnitTes
self.manager.updateObjectDataForPack(oid, orig_serial, None, None)
self.assertEqual(self.manager.getObjectFromTransaction(locking_serial,
oid), None)
+ self.manager.abort(locking_serial, even_if_locked=True)
# Object known, but doesn't point at orig_serial, it is not updated
+ self.manager.register(uuid, locking_serial)
self.manager.storeObject(locking_serial, ram_serial, oid, 0, 512,
'bar', None)
orig_object = self.manager.getObjectFromTransaction(locking_serial,
@@ -380,7 +382,9 @@ class TransactionManagerTests(NeoUnitTes
self.manager.updateObjectDataForPack(oid, orig_serial, None, None)
self.assertEqual(self.manager.getObjectFromTransaction(locking_serial,
oid), orig_object)
+ self.manager.abort(locking_serial, even_if_locked=True)
+ self.manager.register(uuid, locking_serial)
self.manager.storeObject(locking_serial, ram_serial, oid, None, None,
None, other_serial)
orig_object = self.manager.getObjectFromTransaction(locking_serial,
@@ -388,21 +392,26 @@ class TransactionManagerTests(NeoUnitTes
self.manager.updateObjectDataForPack(oid, orig_serial, None, None)
self.assertEqual(self.manager.getObjectFromTransaction(locking_serial,
oid), orig_object)
+ self.manager.abort(locking_serial, even_if_locked=True)
# Object known and points at undone data it gets updated
# ...with data_serial: getObjectData must not be called
+ self.manager.register(uuid, locking_serial)
self.manager.storeObject(locking_serial, ram_serial, oid, None, None,
None, orig_serial)
self.manager.updateObjectDataForPack(oid, orig_serial, new_serial,
None)
self.assertEqual(self.manager.getObjectFromTransaction(locking_serial,
oid), (oid, None, None, None, new_serial))
+ self.manager.abort(locking_serial, even_if_locked=True)
# with data
+ self.manager.register(uuid, locking_serial)
self.manager.storeObject(locking_serial, ram_serial, oid, None, None,
None, orig_serial)
self.manager.updateObjectDataForPack(oid, orig_serial, None,
getObjectData)
self.assertEqual(self.manager.getObjectFromTransaction(locking_serial,
oid), (oid, compression, checksum, value, None))
+ self.manager.abort(locking_serial, even_if_locked=True)
if __name__ == "__main__":
unittest.main()
More information about the Neo-report
mailing list