[Zope3-checkins] SVN: Zope3/branches/ZopeX3-3.0/src/ Add missing sortKey method to ZopeDBTransactionManager and DataManagerAdapter, and also add it to the interface.

Sidnei da Silva sidnei at awkly.org
Wed Jun 23 13:16:16 EDT 2004


Log message for revision 25954:
Add missing sortKey method to ZopeDBTransactionManager and DataManagerAdapter, and also add it to the interface.


-=-
Modified: Zope3/branches/ZopeX3-3.0/src/ZODB/interfaces.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/ZODB/interfaces.py	2004-06-23 17:14:20 UTC (rev 25953)
+++ Zope3/branches/ZopeX3-3.0/src/ZODB/interfaces.py	2004-06-23 17:16:16 UTC (rev 25954)
@@ -144,7 +144,17 @@
 
         """
 
+    def sortKey():
+        """
+        Return a key to use for ordering registered DataManagers
 
+        ZODB uses a global sort order to prevent deadlock when it commits
+        transactions involving multiple resource managers.  The resource
+        manager must define a sortKey() method that provides a global ordering
+        for resource managers.
+        """
+
+
 class ITransaction(Interface):
     """Object representing a running transaction.
 
@@ -224,3 +234,4 @@
         """
         # XXX is this this allowed to cause an exception here, during
         # the two-phase commit, or can it toss data silently?
+

Modified: Zope3/branches/ZopeX3-3.0/src/transaction/_transaction.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/transaction/_transaction.py	2004-06-23 17:14:20 UTC (rev 25953)
+++ Zope3/branches/ZopeX3-3.0/src/transaction/_transaction.py	2004-06-23 17:16:16 UTC (rev 25954)
@@ -580,3 +580,7 @@
     def tpc_vote(self, transaction):
         if not self._sub:
             self._datamanager.prepare(transaction)
+
+    def sortKey(self):
+        return self._datamanager.sortKey()
+

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/__init__.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/__init__.py	2004-06-23 17:14:20 UTC (rev 25953)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/__init__.py	2004-06-23 17:16:16 UTC (rev 25954)
@@ -46,7 +46,7 @@
     """
     Escape data suitable for inclusion in generated ANSI SQL92 code for
     cases where bound variables are not suitable.
-    
+
     >>> sqlquote('''Hi''')
     "'Hi'"
     >>> sqlquote('''It's mine''')
@@ -137,7 +137,7 @@
             # Note: I added the general Exception, since the DA can return
             # implementation-specific errors. But we really want to catch all
             # issues at this point, so that we can convert it to a
-            # DatabaseException. 
+            # DatabaseException.
             except Exception, error:
                 raise DatabaseException, str(error)
 
@@ -389,8 +389,18 @@
         """
 
         return NoSavepointSupportRollback(self)
-    
 
+    def sortKey(self):
+        """
+        ZODB uses a global sort order to prevent deadlock when it commits
+        transactions involving multiple resource managers.  The resource
+        manager must define a sortKey() method that provides a global ordering
+        for resource managers.
+
+        (excerpt from transaction/notes.txt)
+        """
+        return 'rdb' + str(id(self))
+
 class Row(object):
     """Represents a row in a ResultSet"""
 

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/tests/test_zopedbtransactionmanager.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/tests/test_zopedbtransactionmanager.py	2004-06-23 17:14:20 UTC (rev 25953)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/tests/test_zopedbtransactionmanager.py	2004-06-23 17:16:16 UTC (rev 25954)
@@ -43,11 +43,44 @@
         get_transaction().commit()
         self.assertEqual(self.conn._called.get('commit'), 1)
 
+
+class TwoTxnMgrSortKeyTest(TestCase):
+
+    # We test two transaction managers here so that when calling
+    # commit or abort it triggers the code that calls sortKey()
+
+    def setUp(self):
+        self.conn1 = ConnectionStub()
+        self.conn2 = ConnectionStub()
+        zc1 = ZopeConnection(self.conn1, TypeInfoStub())
+        self.datamgr1 = ZopeDBTransactionManager(zc1)
+        zc2 = ZopeConnection(self.conn2, TypeInfoStub())
+        self.datamgr1 = ZopeDBTransactionManager(zc2)
+        zc1.registerForTxn()
+        zc2.registerForTxn()
+        self.txn_factory = get_transaction
+
+    def tearDown(self):
+        """ make sure the global env is clean"""
+        get_transaction().abort()
+
+    def test_abort(self):
+        get_transaction().abort()
+        self.assertEqual(self.conn1._called.get('rollback'), 1)
+        self.assertEqual(self.conn2._called.get('rollback'), 1)
+
+    def test_commit(self):
+        get_transaction().commit()
+        self.assertEqual(self.conn1._called.get('commit'), 1)
+        self.assertEqual(self.conn2._called.get('commit'), 1)
+
+
 def test_suite():
     from doctest import DocTestSuite
     return TestSuite((
         DocTestSuite('zope.app.rdb'),
         makeSuite(TxnMgrTest),
+        makeSuite(TwoTxnMgrTest),
         ))
 
 if __name__=='__main__':




More information about the Zope3-Checkins mailing list