[Zodb-checkins] SVN: ZODB/trunk/ merge 70049:70059 from the
jinty-doom branch.
Brian Sutherland
jinty at web.de
Fri Sep 8 10:55:54 EDT 2006
Log message for revision 70066:
merge 70049:70059 from the jinty-doom branch.
These are the ZODB part of the patches I posted to
http://www.zope.org/Collectors/Zope3-dev/655 with an additional import cleanup.
The issue was silent for over 2 weeks.
Also my attempts at subscribing to zodb-dev or sending a message there
dissapeared were doomed;)
I'm fully willing to revert this if someone has an issue with it.
------------------------------------------------------------------------
r70059 | jinty | 2006-09-08 16:26:44 +0200 (Fri, 08 Sep 2006) | 1 line
Forgot the NEWS entry. Hope I did it right.
------------------------------------------------------------------------
r70053 | jinty | 2006-09-08 14:43:26 +0200 (Fri, 08 Sep 2006) | 1 line
Clean up wierd import dance with ZODB. This is unnecessary since the transaction module stopped being imported in ZODB/__init__.py in rev 39622.
------------------------------------------------------------------------
r70051 | jinty | 2006-09-08 13:24:45 +0200 (Fri, 08 Sep 2006) | 1 line
Add the ability to ask a transaction if it has been doomed i.e. isDoomed().
------------------------------------------------------------------------
r70050 | jinty | 2006-09-08 13:13:06 +0200 (Fri, 08 Sep 2006) | 1 line
Add the doom() function to transactions. Look at tests/doom.txt for more info.
------------------------------------------------------------------------
Changed:
U ZODB/trunk/NEWS.txt
U ZODB/trunk/src/transaction/__init__.py
U ZODB/trunk/src/transaction/_manager.py
U ZODB/trunk/src/transaction/_transaction.py
U ZODB/trunk/src/transaction/interfaces.py
A ZODB/trunk/src/transaction/tests/doom.txt
U ZODB/trunk/src/transaction/tests/test_transaction.py
-=-
Modified: ZODB/trunk/NEWS.txt
===================================================================
--- ZODB/trunk/NEWS.txt 2006-09-08 14:46:08 UTC (rev 70065)
+++ ZODB/trunk/NEWS.txt 2006-09-08 14:55:53 UTC (rev 70066)
@@ -1,3 +1,31 @@
+What's new on ZODB 3.8a1?
+=========================
+
+Transactions
+------------
+
+- (3.8a1) Add a doom() and isDoomed() interface to the transaction module.
+
+ First step towards the resolution of
+ http://www.zope.org/Collectors/Zope3-dev/655
+
+ A doomed transaction behaves exactly the same way as an active transaction
+ but raises an error on any attempt to commit it, thus forcing an abort.
+
+ Doom is useful in places where abort is unsafe and an exception cannot be
+ raised. This occurs when the programmer wants the code following the doom to
+ run but not commit. It is unsafe to abort in these circumstances as a
+ following get() may implicitly open a new transaction.
+
+ Any attempt to commit a doomed transaction will raise a DoomedTransaction
+ exception.
+
+- (3.8a1) Clean up the ZODB imports in transaction.
+
+ Clean up weird import dance with ZODB. This is unnecessary since the
+ transaction module stopped being imported in ZODB/__init__.py in rev 39622.
+
+
What's new on ZODB 3.7b2?
=========================
Modified: ZODB/trunk/src/transaction/__init__.py
===================================================================
--- ZODB/trunk/src/transaction/__init__.py 2006-09-08 14:46:08 UTC (rev 70065)
+++ ZODB/trunk/src/transaction/__init__.py 2006-09-08 14:55:53 UTC (rev 70066)
@@ -24,4 +24,6 @@
begin = manager.begin
commit = manager.commit
abort = manager.abort
+doom = manager.doom
+isDoomed = manager.isDoomed
savepoint = manager.savepoint
Modified: ZODB/trunk/src/transaction/_manager.py
===================================================================
--- ZODB/trunk/src/transaction/_manager.py 2006-09-08 14:46:08 UTC (rev 70065)
+++ ZODB/trunk/src/transaction/_manager.py 2006-09-08 14:55:53 UTC (rev 70066)
@@ -19,9 +19,11 @@
import thread
+from ZODB.utils import WeakSet, deprecated37
+
from transaction._transaction import Transaction
-# Used for deprecated arguments. ZODB.utils.DEPRECATED_ARGUMENT is
+# Used for deprecated arguments. ZODB.utils.DEPRECATED_ARGUMENT was
# too hard to use here, due to the convoluted import dance across
# __init__.py files.
_marker = object()
@@ -34,8 +36,6 @@
# alive (e.g., the cache, and everything reachable from it too).
# Therefore we use "weak sets" internally.
#
-# Obscure: because of the __init__.py maze, we can't import WeakSet
-# at top level here.
# Call the ISynchronizer newTransaction() method on every element of
# WeakSet synchs.
@@ -58,8 +58,6 @@
class TransactionManager(object):
def __init__(self):
- from ZODB.utils import WeakSet
-
self._txn = None
self._synchs = WeakSet()
@@ -85,11 +83,16 @@
def unregisterSynch(self, synch):
self._synchs.remove(synch)
+ def isDoomed(self):
+ return self.get().isDoomed()
+
+ def doom(self):
+ return self.get().doom()
+
def commit(self, sub=_marker):
if sub is _marker:
sub = None
else:
- from ZODB.utils import deprecated37
deprecated37("subtransactions are deprecated; use "
"transaction.savepoint() instead of "
"transaction.commit(1)")
@@ -99,7 +102,6 @@
if sub is _marker:
sub = None
else:
- from ZODB.utils import deprecated37
deprecated37("subtransactions are deprecated; use "
"sp.rollback() instead of "
"transaction.abort(1), where `sp` is the "
@@ -132,7 +134,6 @@
synchs = self._synchs.get(tid)
if synchs is None:
- from ZODB.utils import WeakSet
synchs = self._synchs[tid] = WeakSet()
txn = self._txns[tid] = Transaction(synchs, self)
@@ -145,7 +146,6 @@
if txn is None:
synchs = self._synchs.get(tid)
if synchs is None:
- from ZODB.utils import WeakSet
synchs = self._synchs[tid] = WeakSet()
txn = self._txns[tid] = Transaction(synchs, self)
return txn
@@ -159,7 +159,6 @@
tid = thread.get_ident()
ws = self._synchs.get(tid)
if ws is None:
- from ZODB.utils import WeakSet
ws = self._synchs[tid] = WeakSet()
ws.add(synch)
Modified: ZODB/trunk/src/transaction/_transaction.py
===================================================================
--- ZODB/trunk/src/transaction/_transaction.py 2006-09-08 14:46:08 UTC (rev 70065)
+++ ZODB/trunk/src/transaction/_transaction.py 2006-09-08 14:55:53 UTC (rev 70066)
@@ -169,16 +169,14 @@
from cStringIO import StringIO
from zope import interface
+from ZODB.utils import WeakSet
+from ZODB.utils import deprecated37, deprecated38
+from ZODB.POSException import TransactionFailedError
+from ZODB.utils import oid_repr
+
+
from transaction import interfaces
-# Sigh. In the maze of __init__.py's, ZODB.__init__.py takes 'get'
-# out of transaction.__init__.py, in order to stuff the 'get_transaction'
-# alias in __builtin__. So here in _transaction.py, we can't import
-# exceptions from ZODB.POSException at top level (we're imported by
-# our __init__.py, which is imported by ZODB's __init__, so the ZODB
-# package isn't well-formed when we're first imported).
-# from ZODB.POSException import TransactionError, TransactionFailedError
-
_marker = object()
# The point of this is to avoid hiding exceptions (which the builtin
@@ -193,6 +191,8 @@
COMMITTING = "Committing"
COMMITTED = "Committed"
+ DOOMED = "Doomed"
+
# commit() or commit(True) raised an exception. All further attempts
# to commit or join this transaction will raise TransactionFailedError.
COMMITFAILED = "Commit failed"
@@ -227,7 +227,6 @@
# Weak set of synchronizer objects to call.
if synchronizers is None:
- from ZODB.utils import WeakSet
synchronizers = WeakSet()
self._synchronizers = synchronizers
@@ -258,11 +257,21 @@
# List of (hook, args, kws) tuples added by addAfterCommitHook().
self._after_commit = []
+ def isDoomed(self):
+ return self.status is Status.DOOMED
+
+ def doom(self):
+ if self.status is not Status.DOOMED:
+ if self.status is not Status.ACTIVE:
+ # should not doom transactions in the middle,
+ # or after, a commit
+ raise AssertionError()
+ self.status = Status.DOOMED
+
# Raise TransactionFailedError, due to commit()/join()/register()
# getting called when the current transaction has already suffered
# a commit/savepoint failure.
def _prior_operation_failed(self):
- from ZODB.POSException import TransactionFailedError
assert self._failure_traceback is not None
raise TransactionFailedError("An operation previously failed, "
"with traceback:\n\n%s" %
@@ -272,11 +281,12 @@
if self.status is Status.COMMITFAILED:
self._prior_operation_failed() # doesn't return
- if self.status is not Status.ACTIVE:
+ if (self.status is not Status.ACTIVE and
+ self.status is not Status.DOOMED):
# TODO: Should it be possible to join a committing transaction?
# I think some users want it.
- raise ValueError("expected txn status %r, but it's %r" % (
- Status.ACTIVE, self.status))
+ raise ValueError("expected txn status %r or %r, but it's %r" % (
+ Status.ACTIVE, Status.DOOMED, self.status))
# TODO: the prepare check is a bit of a hack, perhaps it would
# be better to use interfaces. If this is a ZODB4-style
# resource manager, it needs to be adapted, too.
@@ -363,10 +373,12 @@
adapter.objects.append(obj)
def commit(self, subtransaction=_marker, deprecation_wng=True):
+ if self.status is Status.DOOMED:
+ raise interfaces.DoomedTransaction()
+
if subtransaction is _marker:
subtransaction = 0
elif deprecation_wng:
- from ZODB.utils import deprecated37
deprecated37("subtransactions are deprecated; instead of "
"transaction.commit(1), use "
"transaction.savepoint(optimistic=True) in "
@@ -431,7 +443,6 @@
self._before_commit.append((hook, tuple(args), kws))
def beforeCommitHook(self, hook, *args, **kws):
- from ZODB.utils import deprecated38
deprecated38("Use addBeforeCommitHook instead of beforeCommitHook.")
self.addBeforeCommitHook(hook, args, kws)
@@ -539,7 +550,6 @@
if subtransaction is _marker:
subtransaction = 0
elif deprecation_wng:
- from ZODB.utils import deprecated37
deprecated37("subtransactions are deprecated; use "
"sp.rollback() instead of "
"transaction.abort(1), where `sp` is the "
@@ -659,8 +669,6 @@
This function does not raise an exception.
"""
- from ZODB.utils import oid_repr
-
# We should always be able to get __class__.
klass = o.__class__.__name__
# oid would be great, but may this isn't a persistent object.
Modified: ZODB/trunk/src/transaction/interfaces.py
===================================================================
--- ZODB/trunk/src/transaction/interfaces.py 2006-09-08 14:46:08 UTC (rev 70065)
+++ ZODB/trunk/src/transaction/interfaces.py 2006-09-08 14:55:53 UTC (rev 70066)
@@ -45,6 +45,14 @@
"""Abort the current transaction.
"""
+ def doom():
+ """Doom the current transaction.
+ """
+
+ def isDoomed():
+ """Returns True if the current transaction is doomed, otherwise False.
+ """
+
def savepoint(optimistic=False):
"""Create a savepoint from the current transaction.
@@ -115,7 +123,17 @@
This is called from the application. This can only be called
before the two-phase commit protocol has been started.
"""
+
+ def doom():
+ """Doom the transaction.
+ Dooms the current transaction. This will cause
+ DoomedTransactionException to be raised on any attempt to commit the
+ transaction.
+
+ Otherwise the transaction will behave as if it was active.
+ """
+
def savepoint(optimistic=False):
"""Create a savepoint.
@@ -453,3 +471,6 @@
This hook is called when, and only when, a transaction manager's
begin() method is called explictly.
"""
+
+class DoomedTransaction(Exception):
+ """A commit was attempted on a transaction that was doomed."""
Copied: ZODB/trunk/src/transaction/tests/doom.txt (from rev 70065, ZODB/branches/jinty-doom/src/transaction/tests/doom.txt)
Modified: ZODB/trunk/src/transaction/tests/test_transaction.py
===================================================================
--- ZODB/trunk/src/transaction/tests/test_transaction.py 2006-09-08 14:46:08 UTC (rev 70065)
+++ ZODB/trunk/src/transaction/tests/test_transaction.py 2006-09-08 14:55:53 UTC (rev 70066)
@@ -992,8 +992,9 @@
"""
def test_suite():
- from zope.testing.doctest import DocTestSuite
+ from zope.testing.doctest import DocTestSuite, DocFileSuite
return unittest.TestSuite((
+ DocFileSuite('doom.txt'),
DocTestSuite(),
unittest.makeSuite(TransactionTests),
))
More information about the Zodb-checkins
mailing list