[Zodb-checkins] CVS: Packages/ZODB - Connection.py:1.98.4.7
POSException.py:1.20.4.3
Tim Peters
tim.one at comcast.net
Fri Aug 27 15:04:15 EDT 2004
Update of /cvs-repository/Packages/ZODB
In directory cvs.zope.org:/tmp/cvs-serv16182/lib/python/ZODB
Modified Files:
Tag: Zope-2_7-branch
Connection.py POSException.py
Log Message:
New ConnectionStateError raised if an attempt to close a Connection occurs
while a transaction involving that Connection has pending changes.
Collector #789 is a starting point for rationale (short course:
POSKeyErrors, both temporary and permanent, can result otherwise).
The ZODB3 NEWS file will contain more info.
=== Packages/ZODB/Connection.py 1.98.4.6 => 1.98.4.7 ===
--- Packages/ZODB/Connection.py:1.98.4.6 Fri May 21 12:14:04 2004
+++ Packages/ZODB/Connection.py Fri Aug 27 15:03:42 2004
@@ -15,8 +15,16 @@
$Id$"""
+from cPickle import Unpickler, Pickler
+from cStringIO import StringIO
+import sys
+import threading
+from time import time
+from types import StringType, ClassType
+
from cPickleCache import PickleCache
from POSException import ConflictError, ReadConflictError, TransactionError
+from POSException import ConnectionStateError
from ExtensionClass import Base
import ExportImport, TmpStore
from zLOG import LOG, ERROR, BLATHER, WARNING
@@ -25,13 +33,6 @@
from Transaction import Transaction, get_transaction
from ZODB.utils import oid_repr
-from cPickle import Unpickler, Pickler
-from cStringIO import StringIO
-import sys
-import threading
-from time import time
-from types import StringType, ClassType
-
global_code_timestamp = 0
def updateCodeTimestamp():
@@ -53,9 +54,9 @@
The Connection manages movement of objects in and out of object storage.
"""
- _tmp=None
- _debug_info=()
- _opened=None
+ _tmp = None
+ _debug_info = ()
+ _opened = None
_code_timestamp = 0
_transaction = None
@@ -98,6 +99,18 @@
self._invalid = d.has_key
self._conflicts = {}
+ # We want to raise ConnectionStateError if an attempt to close is
+ # made while modifications are pending. This is easier in ZODB
+ # 3.3. While it's not obvious, self._tmp is non-None iff a
+ # committed subtransaction is pending. For "top level" pending
+ # changes, we set _object_registered to True in register(), and
+ # back to False in abort() and _flush_invalidations(). The latter
+ # is an odd choice, but is common to most ways of clearing pending
+ # top-level change (tpc_finish, tpc_abort, sync, _setDB). abort()
+ # is also a bit peculiar, but it's the only Connection method
+ # Transaction.abort() calls, so there's not much choice.
+ self._object_registered = False
+
def getTransaction(self):
t = self._transaction
if t is None:
@@ -258,6 +271,7 @@
else:
assert object._p_oid is not None
self._cache.invalidate(object._p_oid)
+ self._object_registered = False
def cacheFullSweep(self, dt=0):
self._cache.full_sweep(dt)
@@ -274,6 +288,19 @@
self.__onCloseCallbacks.append(f)
def close(self):
+ if self._object_registered:
+ # We're currently joined to a transaction. This spelling
+ # doesn't make much sense here, but I want to keep this
+ # exception the same as in ZODB 3.3 (where this spelling
+ # does make sense).
+ raise ConnectionStateError("Cannot close a connection joined to "
+ "a transaction")
+
+ if self._tmp is not None:
+ # There are no direct modifications pending, but a subtransaction
+ # is pending.
+ raise ConnectionStateError("Cannot close a connection with a "
+ "pending subtransaction")
if self._incrgc is not None:
self._incrgc() # This is a good time to do some GC
@@ -519,6 +546,7 @@
self._inv_lock.release()
# Now is a good time to collect some garbage
self._cache.incrgc()
+ self._object_registered = False
def modifiedInVersion(self, oid):
try: return self._db.modifiedInVersion(oid)
@@ -535,6 +563,7 @@
# XXX Figure out why this assert causes test failures
# assert object._p_oid is not None
self.getTransaction().register(object)
+ self._object_registered = True
def root(self):
return self['\0\0\0\0\0\0\0\0']
=== Packages/ZODB/POSException.py 1.20.4.2 => 1.20.4.3 ===
--- Packages/ZODB/POSException.py:1.20.4.2 Thu Oct 23 20:45:55 2003
+++ Packages/ZODB/POSException.py Fri Aug 27 15:03:42 2004
@@ -219,3 +219,14 @@
XXX The exception ought to have a member that is the invalid object.
"""
+
+class ConnectionStateError(POSError):
+ """A Connection isn't in the required state for an operation.
+
+ o An operation such as a load is attempted on a closed connection.
+
+ o An attempt to close a connection is made while the connection is
+ still joined to a transaction (for example, a transaction is in
+ progress, with uncommitted modifications in the connection).
+ """
+
\ No newline at end of file
More information about the Zodb-checkins
mailing list