[Zodb-checkins] CVS: Zope/lib/python/ZODB - Connection.py:1.79.6.1 DB.py:1.45.6.1 ExportImport.py:1.15.2.1 ZApplication.py:1.11.44.1
Shane Hathaway
shane@zope.com
Tue, 3 Dec 2002 11:03:14 -0500
Update of /cvs-repository/Zope/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv13538
Modified Files:
Tag: shane-local-transactions-branch
Connection.py DB.py ExportImport.py ZApplication.py
Log Message:
Enabled decoupling of ZODB connections and transactions, a feature
requested often on the zodb-dev list.
The Connection class now has a method setLocalTransaction().
(Suggestions for a better method name accepted.) Once your app calls
this, your app is expected to use connection.getTransaction() or
ob._p_jar.getTransaction() instead of the get_transaction() function
to commit or abort the transaction. Doing this enables your
application to have multiple writable connections open in a single
thread, which is especially usefully in GUI applications.
If you don't call setLocalTransaction(), ZODB behaves as it always
has, with transactions bound to threads.
This feature is experimental, but the implementation seems about
right. Unfortunately I had to change the CommitVersion, AbortVersion,
and TransactionalUndo classes so that instances don't automatically
register themselves with the transaction, but they should not have
been doing that in the first place, and hopefully these classes aren't
being used directly by applications. Most apps will see no change.
=== Zope/lib/python/ZODB/Connection.py 1.79 => 1.79.6.1 ===
--- Zope/lib/python/ZODB/Connection.py:1.79 Mon Nov 18 18:17:40 2002
+++ Zope/lib/python/ZODB/Connection.py Tue Dec 3 11:03:13 2002
@@ -22,6 +22,7 @@
from zLOG import LOG, ERROR, BLATHER, WARNING
from coptimizations import new_persistent_id
from ConflictResolution import ResolvedSerial
+from Transaction import Transaction, get_transaction
from cPickle import Unpickler, Pickler
from cStringIO import StringIO
@@ -55,6 +56,7 @@
_debug_info=()
_opened=None
_code_timestamp = 0
+ _transaction = None
# Experimental. Other connections can register to be closed
# when we close by putting something here.
@@ -80,6 +82,18 @@
self._load_count = 0 # Number of objects unghosted
self._store_count = 0 # Number of objects stored
+ def getTransaction(self):
+ t = self._transaction
+ if t is None:
+ # Fall back to thread-bound transactions
+ t = get_transaction()
+ return t
+
+ def setLocalTransaction(self):
+ if self._transaction is None:
+ self._transaction = Transaction()
+ return self._transaction
+
def _cache_items(self):
# find all items on the lru list
items = self._cache.lru_items()
@@ -268,7 +282,7 @@
if self.__onCommitActions is None:
self.__onCommitActions = []
self.__onCommitActions.append((method_name, args, kw))
- get_transaction().register(self)
+ self.getTransaction().register(self)
def commit(self, object, transaction):
if object is self:
@@ -483,7 +497,7 @@
assert object._p_jar is self
# XXX Figure out why this assert causes test failures
# assert object._p_oid is not None
- get_transaction().register(object)
+ self.getTransaction().register(object)
def root(self):
return self['\0\0\0\0\0\0\0\0']
@@ -513,7 +527,7 @@
# read.
if self._invalid(oid):
if not hasattr(object.__class__, '_p_independent'):
- get_transaction().register(self)
+ self.getTransaction().register(self)
raise ReadConflictError(object=object)
invalid = 1
else:
@@ -541,7 +555,7 @@
except KeyError:
pass
else:
- get_transaction().register(self)
+ self.getTransaction().register(self)
raise ConflictError(object=object)
except ConflictError:
@@ -692,7 +706,7 @@
self._db.finish_invalidation()
def sync(self):
- get_transaction().abort()
+ self.getTransaction().abort()
sync=getattr(self._storage, 'sync', 0)
if sync != 0: sync()
self._cache.invalidate(self._invalidated)
@@ -723,7 +737,7 @@
new._p_oid=oid
new._p_jar=self
new._p_changed=1
- get_transaction().register(new)
+ self.getTransaction().register(new)
self._cache[oid]=new
class tConnection(Connection):
=== Zope/lib/python/ZODB/DB.py 1.45 => 1.45.6.1 ===
--- Zope/lib/python/ZODB/DB.py:1.45 Mon Nov 18 18:17:40 2002
+++ Zope/lib/python/ZODB/DB.py Tue Dec 3 11:03:13 2002
@@ -153,8 +153,10 @@
self._temps=t
finally: self._r()
- def abortVersion(self, version):
- AbortVersion(self, version)
+ def abortVersion(self, version, transaction=None):
+ if transaction is None:
+ transaction = get_transaction()
+ transaction.register(AbortVersion(self, version))
def cacheDetail(self):
"""Return information on objects in the various caches
@@ -248,8 +250,10 @@
def close(self):
self._storage.close()
- def commitVersion(self, source, destination=''):
- CommitVersion(self, source, destination)
+ def commitVersion(self, source, destination='', transaction=None):
+ if transaction is None:
+ transaction = get_transaction()
+ transaction.register(CommitVersion(self, source, destination))
def exportFile(self, oid, file=None):
raise 'Not yet implemented'
@@ -545,7 +549,7 @@
def cacheStatistics(self): return () # :(
- def undo(self, id):
+ def undo(self, id, transaction=None):
storage=self._storage
try: supportsTransactionalUndo = storage.supportsTransactionalUndo
except AttributeError:
@@ -555,7 +559,9 @@
if supportsTransactionalUndo:
# new style undo
- TransactionalUndo(self, id)
+ if transaction is None:
+ transaction = get_transaction()
+ transaction.register(TransactionalUndo(self, id))
else:
# fall back to old undo
for oid in storage.undo(id):
@@ -579,7 +585,6 @@
self.tpc_vote=s.tpc_vote
self.tpc_finish=s.tpc_finish
self._sortKey=s.sortKey
- get_transaction().register(self)
def sortKey(self):
return "%s:%s" % (self._sortKey(), id(self))
=== Zope/lib/python/ZODB/ExportImport.py 1.15 => 1.15.2.1 ===
--- Zope/lib/python/ZODB/ExportImport.py:1.15 Mon Dec 2 17:04:37 2002
+++ Zope/lib/python/ZODB/ExportImport.py Tue Dec 3 11:03:13 2002
@@ -76,7 +76,7 @@
return customImporters[magic](self, file, clue)
raise POSException.ExportError, 'Invalid export header'
- t = get_transaction()
+ t = self.getTransaction()
if clue: t.note(clue)
return_oid_list = []
=== Zope/lib/python/ZODB/ZApplication.py 1.11 => 1.11.44.1 ===
--- Zope/lib/python/ZODB/ZApplication.py:1.11 Wed Aug 14 18:07:09 2002
+++ Zope/lib/python/ZODB/ZApplication.py Tue Dec 3 11:03:13 2002
@@ -31,7 +31,7 @@
root=conn.root()
if not root.has_key(name):
root[name]=klass()
- get_transaction().commit()
+ conn.getTransaction().commit()
conn.close()
self._klass=klass