Commit 1b9475d4 authored by Julien Muchembled's avatar Julien Muchembled

Review Connection/DB closure

In addition to some micro-optimisation, this fixes the following minor issues:
- Closing a DB left Connections registered to the global transaction manager.
  Which broke at least multi-db because only such primary connections were
  ignored with monkey-patches.
- Stop calling the real newTransaction when aborting an existing transaction.
  This was not the case if explicit_transactions=0.
parent cb928231
...@@ -283,8 +283,7 @@ class Connection(ExportImport, object): ...@@ -283,8 +283,7 @@ class Connection(ExportImport, object):
raise ConnectionStateError("Cannot close a connection joined to " raise ConnectionStateError("Cannot close a connection joined to "
"a transaction") "a transaction")
if self._cache is not None: self._cache.incrgc() # This is a good time to do some GC
self._cache.incrgc() # This is a good time to do some GC
# Call the close callbacks. # Call the close callbacks.
if self.__onCloseCallbacks is not None: if self.__onCloseCallbacks is not None:
...@@ -734,17 +733,13 @@ class Connection(ExportImport, object): ...@@ -734,17 +733,13 @@ class Connection(ExportImport, object):
def newTransaction(self, transaction, sync=True): def newTransaction(self, transaction, sync=True):
self._readCurrent.clear() self._readCurrent.clear()
self._storage.sync(sync)
try: invalidated = self._storage.poll_invalidations()
self._storage.sync(sync) if invalidated is None:
invalidated = self._storage.poll_invalidations() # special value: the transaction is so old that
if invalidated is None: # we need to flush the whole cache.
# special value: the transaction is so old that invalidated = self._cache.cache_data.copy()
# we need to flush the whole cache. self._cache.invalidate(invalidated)
invalidated = self._cache.cache_data.copy()
self._cache.invalidate(invalidated)
except AttributeError:
assert self._storage is None
def afterCompletion(self, transaction): def afterCompletion(self, transaction):
# Note that we we call newTransaction here for 2 reasons: # Note that we we call newTransaction here for 2 reasons:
...@@ -924,8 +919,7 @@ class Connection(ExportImport, object): ...@@ -924,8 +919,7 @@ class Connection(ExportImport, object):
transaction_manager.registerSynch(self) transaction_manager.registerSynch(self)
if self._cache is not None: self._cache.incrgc() # This is a good time to do some GC
self._cache.incrgc() # This is a good time to do some GC
if delegate: if delegate:
# delegate open to secondary connections # delegate open to secondary connections
...@@ -951,7 +945,7 @@ class Connection(ExportImport, object): ...@@ -951,7 +945,7 @@ class Connection(ExportImport, object):
c._storage.release() c._storage.release()
c._storage = c._normal_storage = None c._storage = c._normal_storage = None
c._cache = PickleCache(self, 0, 0) c._cache = PickleCache(self, 0, 0)
c.transaction_manager = None c.close(False)
########################################################################## ##########################################################################
# Python protocol # Python protocol
......
...@@ -24,7 +24,7 @@ from . import utils ...@@ -24,7 +24,7 @@ from . import utils
from ZODB.broken import find_global from ZODB.broken import find_global
from ZODB.utils import z64 from ZODB.utils import z64
from ZODB.Connection import Connection, TransactionMetaData from ZODB.Connection import Connection, TransactionMetaData, noop
from ZODB._compat import Pickler, _protocol, BytesIO from ZODB._compat import Pickler, _protocol, BytesIO
import ZODB.serialize import ZODB.serialize
...@@ -646,15 +646,15 @@ class DB(object): ...@@ -646,15 +646,15 @@ class DB(object):
is closed, so they stop behaving usefully. Perhaps close() is closed, so they stop behaving usefully. Perhaps close()
should also close all the Connections. should also close all the Connections.
""" """
noop = lambda *a: None
self.close = noop self.close = noop
@self._connectionMap @self._connectionMap
def _(c): def _(conn):
if c.transaction_manager is not None: if conn.transaction_manager is not None:
c.transaction_manager.abort() for c in six.itervalues(conn.connections):
c.afterCompletion = c.newTransaction = c.close = noop c.explicit_transactions = True
c._release_resources() conn.transaction_manager.abort()
conn._release_resources()
self._mvcc_storage.close() self._mvcc_storage.close()
del self.storage del self.storage
......
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