[Zodb-checkins] CVS: Zope/lib/python/ZODB - Connection.py:1.83 DB.py:1.47 ExportImport.py:1.16 ZApplication.py:1.12
Shane Hathaway
shane@zope.com
Fri, 17 Jan 2003 12:23:49 -0500
Update of /cvs-repository/Zope/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv22844
Modified Files:
Connection.py DB.py ExportImport.py ZApplication.py
Log Message:
Merged shane-local-transactions-branch.
This change adds a new method, setLocalTransaction(), to the
Connection class. ZODB applications can call this method to bind
transactions to connections rather than threads. This is especially
useful for GUI applications, which often have only one thread but
multiple independent activities within that thread (generally one per
window). Thanks to Christian Reis for championing this feature.
Applications that take advantage of this feature should not use the
get_transaction() function. Until now, ZODB itself sometimes assumed
get_transaction() was the only way to get the transaction. Minor
corrections have been added. The ZODB test suite, on the other hand,
can continue to use get_transaction(), since it is free to assume that
transactions are bound to threads.
=== Zope/lib/python/ZODB/Connection.py 1.82 => 1.83 ===
--- Zope/lib/python/ZODB/Connection.py:1.82 Wed Jan 15 16:29:26 2003
+++ Zope/lib/python/ZODB/Connection.py Fri Jan 17 12:23:14 2003
@@ -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,19 @@
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):
+ """Use a transaction bound to the connection rather than the thread"""
+ 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()
@@ -269,7 +284,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:
@@ -484,7 +499,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']
@@ -516,7 +531,7 @@
# XXX Need unit tests for _p_independent.
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:
@@ -544,7 +559,7 @@
except KeyError:
pass
else:
- get_transaction().register(self)
+ self.getTransaction().register(self)
raise ConflictError(object=object)
except ConflictError:
@@ -695,7 +710,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)
@@ -726,7 +741,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.46 => 1.47 ===
--- Zope/lib/python/ZODB/DB.py:1.46 Tue Dec 3 12:40:56 2002
+++ Zope/lib/python/ZODB/DB.py Fri Jan 17 12:23:14 2003
@@ -19,7 +19,7 @@
import cPickle, cStringIO, sys, POSException, UndoLogCompatible
from Connection import Connection
from bpthread import allocate_lock
-from Transaction import Transaction
+from Transaction import Transaction, get_transaction
from referencesf import referencesf
from time import time, ctime
from zLOG import LOG, ERROR
@@ -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'
@@ -542,7 +546,7 @@
def cacheStatistics(self): return () # :(
- def undo(self, id):
+ def undo(self, id, transaction=None):
storage=self._storage
try: supportsTransactionalUndo = storage.supportsTransactionalUndo
except AttributeError:
@@ -552,7 +556,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):
@@ -576,7 +582,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))
@@ -613,9 +618,9 @@
in cooperation with a transaction manager.
"""
- # I'm lazy. I'm reusing __init__ and abort and reusing the
- # version attr for the transavtion id. There's such a strong
- # similarity of rythm, that I think it's justified.
+ # I (Jim) am lazy. I'm reusing __init__ and abort and reusing the
+ # version attr for the transaction id. There's such a strong
+ # similarity of rhythm that I think it's justified.
def commit(self, reallyme, t):
db=self._db
=== Zope/lib/python/ZODB/ExportImport.py 1.15 => 1.16 ===
--- Zope/lib/python/ZODB/ExportImport.py:1.15 Mon Dec 2 17:04:37 2002
+++ Zope/lib/python/ZODB/ExportImport.py Fri Jan 17 12:23:14 2003
@@ -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.12 ===
--- Zope/lib/python/ZODB/ZApplication.py:1.11 Wed Aug 14 18:07:09 2002
+++ Zope/lib/python/ZODB/ZApplication.py Fri Jan 17 12:23:14 2003
@@ -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