[Zodb-checkins] SVN: ZODB/branches/jim-clean-up-tpc/src/Z Clean up tpc semantics to allow multiple tpc_begin and tpc_finish calls for the same transaction.
Jim Fulton
jim at zope.com
Wed Dec 23 16:18:57 EST 2009
Log message for revision 107022:
Clean up tpc semantics to allow multiple tpc_begin and tpc_finish calls for the same transaction.
Changed:
U ZODB/branches/jim-clean-up-tpc/src/ZEO/ClientStorage.py
U ZODB/branches/jim-clean-up-tpc/src/ZEO/tests/ConnectionTests.py
U ZODB/branches/jim-clean-up-tpc/src/ZODB/BaseStorage.py
U ZODB/branches/jim-clean-up-tpc/src/ZODB/DemoStorage.py
U ZODB/branches/jim-clean-up-tpc/src/ZODB/MappingStorage.py
U ZODB/branches/jim-clean-up-tpc/src/ZODB/tests/BasicStorage.py
U ZODB/branches/jim-clean-up-tpc/src/ZODB/tests/Synchronization.py
-=-
Modified: ZODB/branches/jim-clean-up-tpc/src/ZEO/ClientStorage.py
===================================================================
--- ZODB/branches/jim-clean-up-tpc/src/ZEO/ClientStorage.py 2009-12-23 21:18:21 UTC (rev 107021)
+++ ZODB/branches/jim-clean-up-tpc/src/ZEO/ClientStorage.py 2009-12-23 21:18:56 UTC (rev 107022)
@@ -1087,17 +1087,19 @@
if self._is_read_only:
raise POSException.ReadOnlyError()
self._tpc_cond.acquire()
- self._midtxn_disconnect = 0
- while self._transaction is not None:
- # It is allowable for a client to call two tpc_begins in a
- # row with the same transaction, and the second of these
- # must be ignored.
- if self._transaction == txn:
- self._tpc_cond.release()
- return
- self._tpc_cond.wait(30)
- self._transaction = txn
- self._tpc_cond.release()
+ try:
+ self._midtxn_disconnect = 0
+ while self._transaction is not None:
+ # It is allowable for a client to call two tpc_begins in a
+ # row with the same transaction, and the second of these
+ # must be ignored.
+ if self._transaction is txn:
+ raise POSException.StorageTransactionError(
+ "Multiple calls to tpc_begin with same transaction")
+ self._tpc_cond.wait(30)
+ self._transaction = txn
+ finally:
+ self._tpc_cond.release()
try:
self._server.tpc_begin(id(txn), txn.user, txn.description,
@@ -1148,7 +1150,8 @@
def tpc_finish(self, txn, f=None):
"""Storage API: finish a transaction."""
if txn is not self._transaction:
- return
+ raise POSException.StorageTransactionError(
+ "tpc_finish called with wrong transaction.")
self._load_lock.acquire()
try:
if self._midtxn_disconnect:
Modified: ZODB/branches/jim-clean-up-tpc/src/ZEO/tests/ConnectionTests.py
===================================================================
--- ZODB/branches/jim-clean-up-tpc/src/ZEO/tests/ConnectionTests.py 2009-12-23 21:18:21 UTC (rev 107021)
+++ ZODB/branches/jim-clean-up-tpc/src/ZEO/tests/ConnectionTests.py 2009-12-23 21:18:56 UTC (rev 107022)
@@ -1093,7 +1093,6 @@
self.assertRaises(ConflictError, storage.tpc_vote, t)
# Even aborting won't help.
storage.tpc_abort(t)
- storage.tpc_finish(t)
# Try again.
obj.value = 10
t = Transaction()
@@ -1103,7 +1102,6 @@
self.assertRaises(ConflictError, storage.tpc_vote, t)
# Abort this one and try a transaction that should succeed.
storage.tpc_abort(t)
- storage.tpc_finish(t)
# Now do a store.
obj.value = 11
t = Transaction()
Modified: ZODB/branches/jim-clean-up-tpc/src/ZODB/BaseStorage.py
===================================================================
--- ZODB/branches/jim-clean-up-tpc/src/ZODB/BaseStorage.py 2009-12-23 21:18:21 UTC (rev 107021)
+++ ZODB/branches/jim-clean-up-tpc/src/ZODB/BaseStorage.py 2009-12-23 21:18:56 UTC (rev 107022)
@@ -221,7 +221,8 @@
self._lock_acquire()
try:
if self._transaction is transaction:
- return
+ raise POSException.StorageTransactionError(
+ "Multiple calls to tpc_begin with same transaction")
self._lock_release()
self._commit_lock_acquire()
self._lock_acquire()
@@ -284,7 +285,8 @@
self._lock_acquire()
try:
if transaction is not self._transaction:
- return
+ raise POSException.StorageTransactionError(
+ "tpc_finish called with wrong transaction.")
try:
if f is not None:
f(self._tid)
Modified: ZODB/branches/jim-clean-up-tpc/src/ZODB/DemoStorage.py
===================================================================
--- ZODB/branches/jim-clean-up-tpc/src/ZODB/DemoStorage.py 2009-12-23 21:18:21 UTC (rev 107021)
+++ ZODB/branches/jim-clean-up-tpc/src/ZODB/DemoStorage.py 2009-12-23 21:18:56 UTC (rev 107022)
@@ -45,7 +45,7 @@
else:
self._temporary_base = False
self.base = base
-
+
if changes is None:
changes = ZODB.MappingStorage.MappingStorage()
zope.interface.alsoProvides(self, ZODB.interfaces.IBlobStorage)
@@ -82,7 +82,7 @@
self.changes = ZODB.blob.BlobStorage(blob_dir, self.changes)
self._copy_methods_from_changes(self.changes)
return True
-
+
def cleanup(self):
self.base.cleanup()
self.changes.cleanup()
@@ -95,7 +95,7 @@
def _copy_methods_from_changes(self, changes):
for meth in (
- '_lock_acquire', '_lock_release',
+ '_lock_acquire', '_lock_release',
'getSize', 'history', 'isReadOnly', 'registerDB',
'sortKey', 'tpc_transaction', 'tpc_vote',
):
@@ -230,7 +230,7 @@
raise TypeError(
"Garbage collection isn't supported"
" when there is a base storage.")
-
+
try:
self.changes.pack(t, referencesf, gc=False)
except TypeError, v:
@@ -262,7 +262,7 @@
old = self.base.load(oid, '')[1]
except ZODB.POSException.POSKeyError:
old = serial
-
+
if old != serial:
raise ZODB.POSException.ConflictError(
oid=oid, serials=(old, serial)) # XXX untested branch
@@ -309,7 +309,8 @@
def tpc_begin(self, transaction, *a, **k):
# The tid argument exists to support testing.
if transaction is self._transaction:
- return
+ raise ZODB.POSException.StorageTransactionError(
+ "Multiple calls to tpc_begin with same transaction")
self._lock_release()
self._commit_lock.acquire()
self._lock_acquire()
@@ -320,7 +321,9 @@
@ZODB.utils.locked
def tpc_finish(self, transaction, func = lambda tid: None):
if (transaction is not self._transaction):
- return
+ raise ZODB.POSException.StorageTransactionError(
+ "tpc_finish called with wrong transaction.")
+
self._issued_oids.difference_update(self._stored_oids)
self._stored_oids = set()
self._transaction = None
@@ -330,7 +333,7 @@
_temporary_blobdirs = {}
def cleanup_temporary_blobdir(
ref,
- _temporary_blobdirs=_temporary_blobdirs, # Make sure it stays around
+ _temporary_blobdirs=_temporary_blobdirs, # Make sure it stays around
):
blob_dir = _temporary_blobdirs.pop(ref, None)
if blob_dir and os.path.exists(blob_dir):
Modified: ZODB/branches/jim-clean-up-tpc/src/ZODB/MappingStorage.py
===================================================================
--- ZODB/branches/jim-clean-up-tpc/src/ZODB/MappingStorage.py 2009-12-23 21:18:21 UTC (rev 107021)
+++ ZODB/branches/jim-clean-up-tpc/src/ZODB/MappingStorage.py 2009-12-23 21:18:56 UTC (rev 107022)
@@ -28,7 +28,7 @@
import zope.interface
class MappingStorage(object):
-
+
zope.interface.implements(
ZODB.interfaces.IStorage,
ZODB.interfaces.IStorageIteration,
@@ -50,7 +50,7 @@
######################################################################
# Preconditions:
-
+
def opened(self):
"""The storage is open
"""
@@ -94,7 +94,7 @@
if tid_data:
return tid_data.maxKey()
raise ZODB.POSException.POSKeyError(oid)
-
+
# ZODB.interfaces.IStorage
@ZODB.utils.locked(opened)
def history(self, oid, size=1):
@@ -124,7 +124,7 @@
def iterator(self, start=None, end=None):
for transaction_record in self._transactions.values(start, end):
yield transaction_record
-
+
# ZODB.interfaces.IStorage
@ZODB.utils.locked(opened)
def lastTransaction(self):
@@ -165,7 +165,7 @@
else:
raise ZODB.POSException.POSKeyError(oid)
-
+
# ZODB.interfaces.IStorage
@ZODB.utils.locked(opened)
def loadSerial(self, oid, serial):
@@ -189,7 +189,7 @@
def pack(self, t, referencesf, gc=True):
if not self._data:
return
-
+
stop = `ZODB.TimeStamp.TimeStamp(*time.gmtime(t)[:5]+(t%60,))`
if self._last_pack is not None and self._last_pack >= stop:
if self._last_pack == stop:
@@ -274,7 +274,8 @@
def tpc_begin(self, transaction, tid=None):
# The tid argument exists to support testing.
if transaction is self._transaction:
- return
+ raise ZODB.POSException.StorageTransactionError(
+ "Multiple calls to tpc_begin with same transaction")
self._lock_release()
self._commit_lock.acquire()
self._lock_acquire()
@@ -292,7 +293,8 @@
@ZODB.utils.locked(opened)
def tpc_finish(self, transaction, func = lambda tid: None):
if (transaction is not self._transaction):
- return
+ raise ZODB.POSException.StorageTransactionError(
+ "tpc_finish called with wrong transaction.")
tid = self._tid
func(tid)
@@ -310,7 +312,7 @@
self._transaction = None
del self._tdata
self._commit_lock.release()
-
+
# ZEO.interfaces.IServeable
@ZODB.utils.locked(opened)
def tpc_transaction(self):
Modified: ZODB/branches/jim-clean-up-tpc/src/ZODB/tests/BasicStorage.py
===================================================================
--- ZODB/branches/jim-clean-up-tpc/src/ZODB/tests/BasicStorage.py 2009-12-23 21:18:21 UTC (rev 107021)
+++ ZODB/branches/jim-clean-up-tpc/src/ZODB/tests/BasicStorage.py 2009-12-23 21:18:56 UTC (rev 107022)
@@ -34,8 +34,8 @@
def checkBasics(self):
t = transaction.Transaction()
self._storage.tpc_begin(t)
- # This should simply return
- self._storage.tpc_begin(t)
+ self.assertRaises(POSException.StorageTransactionError,
+ self._storage.tpc_begin, t)
# Aborting is easy
self._storage.tpc_abort(t)
# Test a few expected exceptions when we're doing operations giving a
Modified: ZODB/branches/jim-clean-up-tpc/src/ZODB/tests/Synchronization.py
===================================================================
--- ZODB/branches/jim-clean-up-tpc/src/ZODB/tests/Synchronization.py 2009-12-23 21:18:21 UTC (rev 107021)
+++ ZODB/branches/jim-clean-up-tpc/src/ZODB/tests/Synchronization.py 2009-12-23 21:18:56 UTC (rev 107022)
@@ -99,19 +99,22 @@
def checkFinishNotCommitting(self):
t = Transaction()
- self._storage.tpc_finish(t)
+ self.assertRaises(StorageTransactionError,
+ self._storage.tpc_finish, t)
self._storage.tpc_abort(t)
def checkFinishWrongTrans(self):
t = Transaction()
self._storage.tpc_begin(t)
- self._storage.tpc_finish(Transaction())
+ self.assertRaises(StorageTransactionError,
+ self._storage.tpc_finish, Transaction())
self._storage.tpc_abort(t)
def checkBeginCommitting(self):
t = Transaction()
self._storage.tpc_begin(t)
- self._storage.tpc_begin(t)
+ self.assertRaises(StorageTransactionError,
+ self._storage.tpc_begin, t)
self._storage.tpc_abort(t)
# TODO: how to check undo?
More information about the Zodb-checkins
mailing list