[Neo-report] r2533 vincent - in /trunk/neo: client/ storage/ tests/storage/

nobody at svn.erp5.org nobody at svn.erp5.org
Tue Dec 14 16:56:56 CET 2010


Author: vincent
Date: Tue Dec 14 16:56:56 2010
New Revision: 2533

Log:
Ignore TID chronology when detecting & resolving conflicts.

If TID allocation and conflict resolution are serialised at database scope
(=cluster scope in NEO), the question doesn't arises: when we have a TID,
we are the latest TID until we call tpc_finish.
If they are not serialised, it means TID allocation will happen after
conflict resolution, as TID generation must be serialised anyway, and in
such case, the temporary TID we have when detecting conflicts has no
ordering signification, so it is meaningless to check their chronology.

Modified:
    trunk/neo/client/app.py
    trunk/neo/storage/transactions.py
    trunk/neo/tests/storage/testTransactions.py

Modified: trunk/neo/client/app.py
==============================================================================
--- trunk/neo/client/app.py [iso-8859-1] (original)
+++ trunk/neo/client/app.py [iso-8859-1] Tue Dec 14 16:56:56 2010
@@ -816,28 +816,23 @@ class Application(object):
             tid = local_var.tid
             resolved = False
             if data is not None:
-                if conflict_serial <= tid:
-                    new_data = tryToResolveConflict(oid, conflict_serial,
-                        serial, data)
-                    if new_data is not None:
-                        neo.logging.info('Conflict resolution succeed for ' \
-                            '%r:%r with %r', dump(oid), dump(serial),
-                            dump(conflict_serial))
-                        # Mark this conflict as resolved
-                        resolved_serial_set.update(conflict_serial_dict.pop(
-                            oid))
-                        # Try to store again
-                        self._store(oid, conflict_serial, new_data)
-                        append(oid)
-                        resolved = True
-                    else:
-                        neo.logging.info('Conflict resolution failed for ' \
-                            '%r:%r with %r', dump(oid), dump(serial),
-                            dump(conflict_serial))
+                new_data = tryToResolveConflict(oid, conflict_serial,
+                    serial, data)
+                if new_data is not None:
+                    neo.logging.info('Conflict resolution succeed for ' \
+                        '%r:%r with %r', dump(oid), dump(serial),
+                        dump(conflict_serial))
+                    # Mark this conflict as resolved
+                    resolved_serial_set.update(conflict_serial_dict.pop(
+                        oid))
+                    # Try to store again
+                    self._store(oid, conflict_serial, new_data)
+                    append(oid)
+                    resolved = True
                 else:
-                    neo.logging.info('Conflict reported for %r:%r with ' \
-                        'later transaction %r , cannot resolve conflict.',
-                        dump(oid), dump(serial), dump(conflict_serial))
+                    neo.logging.info('Conflict resolution failed for ' \
+                        '%r:%r with %r', dump(oid), dump(serial),
+                        dump(conflict_serial))
             if not resolved:
                 # XXX: Is it really required to remove from data_dict ?
                 del data_dict[oid]

Modified: trunk/neo/storage/transactions.py
==============================================================================
--- trunk/neo/storage/transactions.py [iso-8859-1] (original)
+++ trunk/neo/storage/transactions.py [iso-8859-1] Tue Dec 14 16:56:56 2010
@@ -220,17 +220,11 @@ class TransactionManager(object):
                 raise ConflictError(history_list[0][0])
             neo.logging.info('Transaction %s storing %s', dump(tid), dump(oid))
             self._store_lock_dict[oid] = tid
-        elif locking_tid < tid:
+        else:
             # a previous transaction lock this object, retry later
             neo.logging.info('Store delayed for %r:%r by %r', dump(oid),
                     dump(tid), dump(locking_tid))
             raise DelayedError
-        else:
-            # If a newer transaction already locks this object,
-            # do not try to resolve a conflict, so return immediately.
-            neo.logging.info('Unresolvable conflict on %r:%r with %r',
-                dump(oid), dump(tid), dump(locking_tid))
-            raise ConflictError(locking_tid)
 
     def checkCurrentSerial(self, tid, serial, oid):
         self.lockObject(tid, serial, oid)

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] Tue Dec 14 16:56:56 2010
@@ -155,26 +155,6 @@ class TransactionManagerTests(NeoUnitTes
         self.assertRaises(DelayedError, self.manager.storeObject,
                 tid2, serial, *obj)
 
-    def testUnresolvableConflict(self):
-        """ A newer transaction has already modified an object """
-        uuid = self.getNewUUID()
-        tid1, txn1 = self._getTransaction()
-        tid2, txn2 = self._getTransaction()
-        serial, obj = self._getObject(1)
-        # the (later) transaction lock (change) the object
-        self.manager.register(uuid, tid2)
-        self.manager.storeTransaction(tid2, *txn2)
-        self.manager.storeObject(tid2, serial, *obj)
-        self.assertTrue(tid2 in self.manager)
-        self._storeTransactionObjects(tid2, txn2)
-        self.manager.lock(tid2, txn2[0])
-        # the previous it's not using the latest version
-        self.manager.register(uuid, tid1)
-        self.manager.storeTransaction(tid1, *txn1)
-        self.assertTrue(tid1 in self.manager)
-        self.assertRaises(ConflictError, self.manager.storeObject,
-                tid1, serial, *obj)
-
     def testResolvableConflict(self):
         """ Try to store an object with the lastest revision """
         uuid = self.getNewUUID()
@@ -229,13 +209,13 @@ class TransactionManagerTests(NeoUnitTes
         self.manager.storeObject(tid2, serial2, *obj2)
         self.assertTrue(tid2 in self.manager)
         self.manager.lock(tid2, txn1[0])
-        # the first get a conflict
+        # the first get a delay, as nothing is committed yet
         self.manager.register(uuid1, tid1)
         self.manager.storeTransaction(tid1, *txn1)
         self.assertTrue(tid1 in self.manager)
-        self.assertRaises(ConflictError, self.manager.storeObject,
+        self.assertRaises(DelayedError, self.manager.storeObject,
                 tid1, serial1, *obj1)
-        self.assertRaises(ConflictError, self.manager.storeObject,
+        self.assertRaises(DelayedError, self.manager.storeObject,
                 tid1, serial2, *obj2)
 
     def testAbortUnlocked(self):




More information about the Neo-report mailing list