[Zodb-checkins] SVN: ZODB/branches/tim-transactions/src/ Make the sample ResourceManager work more the way in which we

Tim Peters tim.one at comcast.net
Tue Jun 29 18:57:16 EDT 2004


Log message for revision 26005:
Make the sample ResourceManager work more the way in which we
intend real implementations to work, and beefed up the tests
to match.  The collaboration also got a little simpler.



-=-
Modified: ZODB/branches/tim-transactions/src/ZODB/collaborations.txt
===================================================================
--- ZODB/branches/tim-transactions/src/ZODB/collaborations.txt	2004-06-29 21:33:48 UTC (rev 26004)
+++ ZODB/branches/tim-transactions/src/ZODB/collaborations.txt	2004-06-29 22:57:16 UTC (rev 26005)
@@ -124,13 +124,12 @@
             C3.regisiter(o3)
                 T.join(C3)
         S1.rollback()
-            S2.rollback()
+            S2.discard()
                 T.discard()
                     C1.discard()
                     C2.discard()
                     C3.discard()
                         o3.invalidate()
-            S2.discard()
                 s21.discard() # roll back changes since previous, which is r11
                     C1.discard(s21)
                         o1.invalidate()

Modified: ZODB/branches/tim-transactions/src/transaction/interfaces.py
===================================================================
--- ZODB/branches/tim-transactions/src/transaction/interfaces.py	2004-06-29 21:33:48 UTC (rev 26004)
+++ ZODB/branches/tim-transactions/src/transaction/interfaces.py	2004-06-29 22:57:16 UTC (rev 26005)
@@ -409,11 +409,10 @@
         """
 
     def discard():
-        """Discard changes saved by this savepoint.
+        """Discard changes saved by and after this savepoint.
 
         That means changes made since the immediately preceding
-        savepoint if one exists, or since the start of the transaction,
-        until this savepoint.
+        savepoint if one exists, or since the start of the transaction.
 
         Once a savepoint has been discarded, it's an error to attempt
         to rollback or discard it again.

Modified: ZODB/branches/tim-transactions/src/transaction/tests/test_SampleResourceManager.py
===================================================================
--- ZODB/branches/tim-transactions/src/transaction/tests/test_SampleResourceManager.py	2004-06-29 21:33:48 UTC (rev 26004)
+++ ZODB/branches/tim-transactions/src/transaction/tests/test_SampleResourceManager.py	2004-06-29 22:57:16 UTC (rev 26005)
@@ -86,6 +86,7 @@
         self.transaction = None
         self.delta = 0
         self.txn_state = None
+        self.first_savepoint = None
 
     def _check_state(self, *ok_states):
         if self.txn_state not in ok_states:
@@ -215,6 +216,9 @@
         self.transaction = None
         self.prepared = False
         self.txn_state = None
+        if self.first_savepoint is not None:
+            self.first_savepoint.invalidate()
+            self.first_savepoint = None
 
     def tpc_abort(self, transaction):
         """Abort a transaction
@@ -365,7 +369,7 @@
         >>> r2.rollback()
         Traceback (most recent call last):
         ...
-        TypeError: ('Attempt to roll back to invalid save point', 3, 2)
+        ValueError: operation attempted on invalid SavePoint
 
         We can roll back to a savepoint as often as we like:
 
@@ -394,39 +398,70 @@
         >>> r1.rollback()
         Traceback (most recent call last):
         ...
-        TypeError: Attempt to rollback stale rollback
-
+        ValueError: operation attempted on invalid SavePoint
         """
         if self.txn_state is not None:
             raise TypeError("Can't get savepoint during two-phase commit")
         self._checkTransaction(transaction)
         self.transaction = transaction
         self.sp += 1
-        return SavePoint(self)
+        if self.first_savepoint is None:
+            savepoint = SavePoint(self, 0)
+            self.first_savepoint = savepoint
+        else:
+            savepoint = SavePoint(self, self.first_savepoint.delta)
+            self.first_savepoint.last_savepoint().next_savepoint = savepoint
+        return savepoint
 
     def discard(self, transaction):
-        pass
+        if self.first_savepoint is None:
+            self.delta = 0
+        else:
+            self.delta = self.first_savepoint.last_savepoint().delta
 
 class SavePoint(object):
 
-    def __init__(self, rm):
+    def __init__(self, rm, olddelta):
         self.rm = rm
+        self.olddelta = olddelta
         self.sp = rm.sp
         self.delta = rm.delta
         self.transaction = rm.transaction
+        self.next_savepoint = None
+        self.valid = True
 
+    def _valid_check(self):
+        if not self.valid:
+            raise ValueError("operation attempted on invalid SavePoint")
+
     def rollback(self):
-        if self.transaction is not self.rm.transaction:
-            raise TypeError("Attempt to rollback stale rollback")
-        if self.rm.sp < self.sp:
-            raise TypeError("Attempt to roll back to invalid save point",
-                            self.sp, self.rm.sp)
-        self.rm.sp = self.sp
-        self.rm.delta = self.delta
+        self._valid_check()
+        if self.next_savepoint is None:
+            self.rm.discard(self.transaction)
+        else:
+            self.next_savepoint.discard()
+        self.next_savepoint = None
 
     def discard(self):
-        pass
+        self._valid_check()
+        if self.next_savepoint is None:
+            self.rm.discard(self.transaction)
+        else:
+            self.next_savepoint.discard()
+        self.rm.delta = self.olddelta
+        self.valid = False
 
+    def last_savepoint(self):
+        """Return the last savepoint in the chain starting at self."""
+        while self.next_savepoint is not None:
+            self = self.next_savepoint
+        return self
+
+    def invalidate(self):
+        self.valid = False
+        if self.next_savepoint is not None:
+            self.next_savepoint.invalidate()
+
 def test_suite():
     from doctest import DocTestSuite
     return DocTestSuite()



More information about the Zodb-checkins mailing list