[Checkins] SVN: transaction/branches/sphinx/ Move datamanager narrative to Sphinx docs.
Tres Seaver
cvs-admin at zope.org
Mon Dec 17 20:28:52 UTC 2012
Log message for revision 128702:
Move datamanager narrative to Sphinx docs.
Changed:
_U transaction/branches/sphinx/
U transaction/branches/sphinx/docs/index.rst
U transaction/branches/sphinx/transaction/tests/test_SampleDataManager.py
-=-
Modified: transaction/branches/sphinx/docs/index.rst
===================================================================
--- transaction/branches/sphinx/docs/index.rst 2012-12-17 20:28:51 UTC (rev 128701)
+++ transaction/branches/sphinx/docs/index.rst 2012-12-17 20:28:52 UTC (rev 128702)
@@ -9,6 +9,7 @@
convenience
doom
savepoint
+ datamanager
api
Modified: transaction/branches/sphinx/transaction/tests/test_SampleDataManager.py
===================================================================
--- transaction/branches/sphinx/transaction/tests/test_SampleDataManager.py 2012-12-17 20:28:51 UTC (rev 128701)
+++ transaction/branches/sphinx/transaction/tests/test_SampleDataManager.py 2012-12-17 20:28:52 UTC (rev 128702)
@@ -12,79 +12,13 @@
#
##############################################################################
"""Sample objects for use in tests
+
+Used by the 'datamanaber' chapter in the Sphinx docs.
"""
-from doctest import DocTestSuite
class DataManager(object):
"""Sample data manager
-
- This class provides a trivial data-manager implementation and doc
- strings to illustrate the the protocol and to provide a tool for
- writing tests.
-
- Our sample data manager has state that is updated through an inc
- method and through transaction operations.
-
- When we create a sample data manager:
-
- >>> dm = DataManager()
-
- It has two bits of state, state:
-
- >>> dm.state
- 0
-
- and delta:
-
- >>> dm.delta
- 0
-
- Both of which are initialized to 0. state is meant to model
- committed state, while delta represents tentative changes within a
- transaction. We change the state by calling inc:
-
- >>> dm.inc()
-
- which updates delta:
-
- >>> dm.delta
- 1
-
- but state isn't changed until we commit the transaction:
-
- >>> dm.state
- 0
-
- To commit the changes, we use 2-phase commit. We execute the first
- stage by calling prepare. We need to pass a transation. Our
- sample data managers don't really use the transactions for much,
- so we'll be lazy and use strings for transactions:
-
- >>> t1 = '1'
- >>> dm.prepare(t1)
-
- The sample data manager updates the state when we call prepare:
-
- >>> dm.state
- 1
- >>> dm.delta
- 1
-
- This is mainly so we can detect some affect of calling the methods.
-
- Now if we call commit:
-
- >>> dm.commit(t1)
-
- Our changes are"permanent". The state reflects the changes and the
- delta has been reset to 0.
-
- >>> dm.state
- 1
- >>> dm.delta
- 0
- """
-
+ """
def __init__(self):
self.state = 0
self.sp = 0
@@ -96,50 +30,6 @@
self.delta += n
def prepare(self, transaction):
- """Prepare to commit data
-
- >>> dm = DataManager()
- >>> dm.inc()
- >>> t1 = '1'
- >>> dm.prepare(t1)
- >>> dm.commit(t1)
- >>> dm.state
- 1
- >>> dm.inc()
- >>> t2 = '2'
- >>> dm.prepare(t2)
- >>> dm.abort(t2)
- >>> dm.state
- 1
-
- It is en error to call prepare more than once without an intervening
- commit or abort:
-
- >>> dm.prepare(t1)
-
- >>> dm.prepare(t1)
- Traceback (most recent call last):
- ...
- TypeError: Already prepared
-
- >>> dm.prepare(t2)
- Traceback (most recent call last):
- ...
- TypeError: Already prepared
-
- >>> dm.abort(t1)
-
- If there was a preceeding savepoint, the transaction must match:
-
- >>> rollback = dm.savepoint(t1)
- >>> dm.prepare(t2)
- Traceback (most recent call last):
- ,,,
- TypeError: ('Transaction missmatch', '2', '1')
-
- >>> dm.prepare(t1)
-
- """
if self.prepared:
raise TypeError('Already prepared')
self._checkTransaction(transaction)
@@ -154,70 +44,6 @@
transaction, self.transaction)
def abort(self, transaction):
- """Abort a transaction
-
- The abort method can be called before two-phase commit to
- throw away work done in the transaction:
-
- >>> dm = DataManager()
- >>> dm.inc()
- >>> dm.state, dm.delta
- (0, 1)
- >>> t1 = '1'
- >>> dm.abort(t1)
- >>> dm.state, dm.delta
- (0, 0)
-
- The abort method also throws away work done in savepoints:
-
- >>> dm.inc()
- >>> r = dm.savepoint(t1)
- >>> dm.inc()
- >>> r = dm.savepoint(t1)
- >>> dm.state, dm.delta
- (0, 2)
- >>> dm.abort(t1)
- >>> dm.state, dm.delta
- (0, 0)
-
- If savepoints are used, abort must be passed the same
- transaction:
-
- >>> dm.inc()
- >>> r = dm.savepoint(t1)
- >>> t2 = '2'
- >>> dm.abort(t2)
- Traceback (most recent call last):
- ...
- TypeError: ('Transaction missmatch', '2', '1')
-
- >>> dm.abort(t1)
-
- The abort method is also used to abort a two-phase commit:
-
- >>> dm.inc()
- >>> dm.state, dm.delta
- (0, 1)
- >>> dm.prepare(t1)
- >>> dm.state, dm.delta
- (1, 1)
- >>> dm.abort(t1)
- >>> dm.state, dm.delta
- (0, 0)
-
- Of course, the transactions passed to prepare and abort must
- match:
-
- >>> dm.prepare(t1)
- >>> dm.abort(t2)
- Traceback (most recent call last):
- ...
- TypeError: ('Transaction missmatch', '2', '1')
-
- >>> dm.abort(t1)
-
-
- """
self._checkTransaction(transaction)
if self.transaction is not None:
self.transaction = None
@@ -229,48 +55,6 @@
self.delta = 0
def commit(self, transaction):
- """Complete two-phase commit
-
- >>> dm = DataManager()
- >>> dm.state
- 0
- >>> dm.inc()
-
- We start two-phase commit by calling prepare:
-
- >>> t1 = '1'
- >>> dm.prepare(t1)
-
- We complete it by calling commit:
-
- >>> dm.commit(t1)
- >>> dm.state
- 1
-
- It is an error ro call commit without calling prepare first:
-
- >>> dm.inc()
- >>> t2 = '2'
- >>> dm.commit(t2)
- Traceback (most recent call last):
- ...
- TypeError: Not prepared to commit
-
- >>> dm.prepare(t2)
- >>> dm.commit(t2)
-
- If course, the transactions given to prepare and commit must
- be the same:
-
- >>> dm.inc()
- >>> t3 = '3'
- >>> dm.prepare(t3)
- >>> dm.commit(t2)
- Traceback (most recent call last):
- ...
- TypeError: ('Transaction missmatch', '2', '3')
-
- """
if not self.prepared:
raise TypeError('Not prepared to commit')
self._checkTransaction(transaction)
@@ -279,105 +63,6 @@
self.prepared = False
def savepoint(self, transaction):
- """Provide the ability to rollback transaction state
-
- Savepoints provide a way to:
-
- - Save partial transaction work. For some data managers, this
- could allow resources to be used more efficiently.
-
- - Provide the ability to revert state to a point in a
- transaction without aborting the entire transaction. In
- other words, savepoints support partial aborts.
-
- Savepoints don't use two-phase commit. If there are errors in
- setting or rolling back to savepoints, the application should
- abort the containing transaction. This is *not* the
- responsibility of the data manager.
-
- Savepoints are always associated with a transaction. Any work
- done in a savepoint's transaction is tentative until the
- transaction is committed using two-phase commit.
-
- >>> dm = DataManager()
- >>> dm.inc()
- >>> t1 = '1'
- >>> r = dm.savepoint(t1)
- >>> dm.state, dm.delta
- (0, 1)
- >>> dm.inc()
- >>> dm.state, dm.delta
- (0, 2)
- >>> r.rollback()
- >>> dm.state, dm.delta
- (0, 1)
- >>> dm.prepare(t1)
- >>> dm.commit(t1)
- >>> dm.state, dm.delta
- (1, 0)
-
- Savepoints must have the same transaction:
-
- >>> r1 = dm.savepoint(t1)
- >>> dm.state, dm.delta
- (1, 0)
- >>> dm.inc()
- >>> dm.state, dm.delta
- (1, 1)
- >>> t2 = '2'
- >>> r2 = dm.savepoint(t2)
- Traceback (most recent call last):
- ...
- TypeError: ('Transaction missmatch', '2', '1')
-
- >>> r2 = dm.savepoint(t1)
- >>> dm.inc()
- >>> dm.state, dm.delta
- (1, 2)
-
- If we rollback to an earlier savepoint, we discard all work
- done later:
-
- >>> r1.rollback()
- >>> dm.state, dm.delta
- (1, 0)
-
- and we can no longer rollback to the later savepoint:
-
- >>> r2.rollback()
- Traceback (most recent call last):
- ...
- TypeError: ('Attempt to roll back to invalid save point', 3, 2)
-
- We can roll back to a savepoint as often as we like:
-
- >>> r1.rollback()
- >>> r1.rollback()
- >>> r1.rollback()
- >>> dm.state, dm.delta
- (1, 0)
-
- >>> dm.inc()
- >>> dm.inc()
- >>> dm.inc()
- >>> dm.state, dm.delta
- (1, 3)
- >>> r1.rollback()
- >>> dm.state, dm.delta
- (1, 0)
-
- But we can't rollback to a savepoint after it has been
- committed:
-
- >>> dm.prepare(t1)
- >>> dm.commit(t1)
-
- >>> r1.rollback()
- Traceback (most recent call last):
- ...
- TypeError: Attempt to rollback stale rollback
-
- """
if self.prepared:
raise TypeError("Can't get savepoint during two-phase commit")
self._checkTransaction(transaction)
@@ -385,6 +70,7 @@
self.sp += 1
return Rollback(self)
+
class Rollback(object):
def __init__(self, dm):
@@ -401,13 +87,3 @@
self.sp, self.dm.sp)
self.dm.sp = self.sp
self.dm.delta = self.delta
-
-
-def test_suite():
- return DocTestSuite()
-
-# additional_tests is for setuptools "setup.py test" support
-additional_tests = test_suite
-
-if __name__ == '__main__':
- unittest.main()
More information about the checkins
mailing list