Commit bf9f6bb5 authored by Tim Peters's avatar Tim Peters

Merge/port assorted ZODB changes checked into Zope3's ZODB copy.

Please don't do that:  ZODB changes need to be done in the ZODB
project.  Checkins to Zope3 have no effect on ZODB in reality.

This includes:

r26945 | jim | 2004-08-06 18:30:44 -0400 (Fri, 06 Aug 2004) | 6 lines
   M /Zope3/trunk/src/persistent/tests/test_persistent.py

Updated to work with the versions of doctest from Python with versions
  greater than or equal to 2.3.0 and less than 2.4.0.a2 and with
  versions greater than 2.4.0a2.

r26482 | srichter | 2004-07-13 13:07:03 -0400 (Tue, 13 Jul 2004) | 2 lines
   M /Zope3/trunk/src/transaction/__init__.py
   M /Zope3/trunk/src/transaction/_transaction.py
   M /Zope3/trunk/src/transaction/tests/test_transaction.py

Converted XXX to TODO.

r25953 | sidnei | 2004-06-23 13:14:20 -0400 (Wed, 23 Jun 2004) | 1 line
   M /Zope3/trunk/src/ZODB/interfaces.py
   M /Zope3/trunk/src/transaction/_transaction.py

Add missing sortKey method to ZopeDBTransactionManager and DataManagerAdapter,
and also add it to the interface.

r25273 | philikon | 2004-06-06 04:43:57 -0400 (Sun, 06 Jun 2004) | 4 lines
Changed paths:
   M /Zope3/trunk/src/BTrees
   M /Zope3/trunk/src/ZODB
   M /Zope3/trunk/src/persistent

Ignore .so files.

This fix should probably be merged to the original ZODB tree.
parent caa12063
......@@ -25,23 +25,30 @@ class P(Persistent):
def inc(self):
self.x += 1
def DocFileSuite(path, globs=None):
try:
DocFileSuite = doctest.DocFileSuite # >= Python 2.4.0a2
except AttributeError:
# <= Python 2.4.0a1
def DocFileSuite(path, globs=None):
# It's not entirely obvious how to connection this single string
# with unittest. For now, re-use the _utest() function that comes
# standard with doctest in Python 2.3. One problem is that the
# error indicator doesn't point to the line of the doctest file
# that failed.
path = os.path.join(persistent.tests.__path__[0], path)
source = open(path).read()
if globs is None:
globs = sys._getframe(1).f_globals
t = doctest.Tester(globs=globs)
def runit():
doctest._utest(t, path, source, path, 0)
f = unittest.FunctionTestCase(runit, description="doctest from %s" % path)
f = unittest.FunctionTestCase(runit,
description="doctest from %s" % path)
suite = unittest.TestSuite()
suite.addTest(f)
return suite
def test_suite():
path = os.path.join(persistent.tests.__path__[0], "persistent.txt")
return DocFileSuite(path, {"P": P})
return DocFileSuite("persistent.txt", globs={"P": P})
......@@ -11,6 +11,10 @@
# FOR A PARTICULAR PURPOSE.
#
############################################################################
"""Exported transaction functions.
$Id$
"""
from transaction._transaction import Transaction
from transaction._manager import TransactionManager, ThreadTransactionManager
......@@ -29,5 +33,5 @@ def commit(sub=False):
def abort(sub=False):
manager.get().abort(sub)
# XXX Issue deprecation warning if this variant is used?
# TODO: Issue deprecation warning if this variant is used?
get_transaction = get
......@@ -25,7 +25,7 @@ Transaction has two methods for a resource manager to call to
participate in a transaction -- register() and join(). join() takes a
resource manager and adds it to the list of resources. register() is
for backwards compatibility. It takes a persistent object and
registers its _p_jar attribute. XXX explain adapter
registers its _p_jar attribute. TODO: explain adapter
Subtransactions
---------------
......@@ -54,7 +54,7 @@ methods and support a second argument to tpc_begin().
The second argument to tpc_begin() indicates that a subtransaction
commit is beginning (if it is true). In a subtransaction, there is no
tpc_vote() call. (XXX I don't have any idea why.) The tpc_finish()
tpc_vote() call. (XXX: I don't have any idea why.) The tpc_finish()
or tpc_abort() call applies just to that subtransaction.
Once a resource manager is involved in a subtransaction, all
......@@ -187,11 +187,11 @@ class Transaction(object):
def join(self, resource):
if self.status != Status.ACTIVE:
# XXX Should it be possible to join a committing transaction?
# 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))
# XXX the prepare check is a bit of a hack, perhaps it would
# 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.
if myhasattr(resource, "prepare"):
......@@ -219,7 +219,7 @@ class Transaction(object):
self._adapters[manager] = adapter
self.join(adapter)
else:
# XXX comment out this expensive assert later
# TODO: comment out this expensive assert later
# Use id() to guard against proxies.
assert id(obj) not in map(id, adapter.objects)
adapter.objects.append(obj)
......@@ -230,7 +230,7 @@ class Transaction(object):
self._resources.append(adapter)
def begin(self):
# XXX I'm not sure how this should be implemented. Not doing
# TODO: I'm not sure how this should be implemented. Not doing
# anything now, but my best guess is: If nothing has happened
# yet, it's fine. Otherwise, abort this transaction and let
# the txn manager create a new one.
......@@ -293,8 +293,8 @@ class Transaction(object):
for rm in L:
rm.tpc_finish(self)
except:
# XXX do we need to make this warning stronger?
# XXX It would be nice if the system could be configured
# TODO: do we need to make this warning stronger?
# TODO: It would be nice if the system could be configured
# to stop committing transactions at this point.
self.log.critical("A storage error occured during the second "
"phase of the two-phase commit. Resources "
......@@ -365,8 +365,8 @@ class Transaction(object):
# Merge all of _sub, _nonsub, and _resources.
d = dict(self._sub)
d.update(self._nonsub)
# XXX I think _sub and _nonsub are disjoint, and that
# XXX _resources is empty. If so, we can simplify this code.
# TODO: I think _sub and _nonsub are disjoint, and that
# _resources is empty. If so, we can simplify this code.
assert len(d) == len(self._sub) + len(self._nonsub)
assert not self._resources
for rm in self._resources:
......@@ -430,7 +430,7 @@ class Transaction(object):
def setExtendedInfo(self, name, value):
self._extension[name] = value
# XXX We need a better name for the adapters.
# TODO: We need a better name for the adapters.
class MultiObjectResourceAdapter(object):
"""Adapt the old-style register() call to the new-style join().
......@@ -538,7 +538,7 @@ class DataManagerAdapter(object):
self._datamanager = datamanager
self._rollback = None
# XXX I'm not sure why commit() doesn't do anything
# TODO: I'm not sure why commit() doesn't do anything
def commit(self, transaction):
pass
......@@ -580,3 +580,7 @@ class DataManagerAdapter(object):
def tpc_vote(self, transaction):
if not self._sub:
self._datamanager.prepare(transaction)
def sortKey(self):
return self._datamanager.sortKey()
......@@ -235,6 +235,16 @@ class IDataManagerOriginal(zope.interface.Interface):
"""
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 IDataManager(zope.interface.Interface):
"""Data management interface for storing objects transactionally.
......@@ -314,6 +324,16 @@ class IDataManager(zope.interface.Interface):
"""
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(zope.interface.Interface):
"""Object representing a running transaction.
......
......@@ -203,7 +203,7 @@ class TransactionTests(unittest.TestCase):
assert self.nosub1._p_jar.ctpc_finish == 0
assert self.nosub1._p_jar.cabort == 1
# XXX
# XXX:
def BUGtestNSJSubTransactionCommitAbort(self):
"""
this reveals a bug in transaction.py
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment