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):
raise ConnectionStateError("Cannot close a connection joined to "
"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.
if self.__onCloseCallbacks is not None:
......@@ -734,17 +733,13 @@ class Connection(ExportImport, object):
def newTransaction(self, transaction, sync=True):
self._readCurrent.clear()
try:
self._storage.sync(sync)
invalidated = self._storage.poll_invalidations()
if invalidated is None:
# special value: the transaction is so old that
# we need to flush the whole cache.
invalidated = self._cache.cache_data.copy()
self._cache.invalidate(invalidated)
except AttributeError:
assert self._storage is None
self._storage.sync(sync)
invalidated = self._storage.poll_invalidations()
if invalidated is None:
# special value: the transaction is so old that
# we need to flush the whole cache.
invalidated = self._cache.cache_data.copy()
self._cache.invalidate(invalidated)
def afterCompletion(self, transaction):
# Note that we we call newTransaction here for 2 reasons:
......@@ -924,8 +919,7 @@ class Connection(ExportImport, object):
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:
# delegate open to secondary connections
......@@ -951,7 +945,7 @@ class Connection(ExportImport, object):
c._storage.release()
c._storage = c._normal_storage = None
c._cache = PickleCache(self, 0, 0)
c.transaction_manager = None
c.close(False)
##########################################################################
# Python protocol
......
......@@ -24,7 +24,7 @@ from . import utils
from ZODB.broken import find_global
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
import ZODB.serialize
......@@ -646,15 +646,15 @@ class DB(object):
is closed, so they stop behaving usefully. Perhaps close()
should also close all the Connections.
"""
noop = lambda *a: None
self.close = noop
@self._connectionMap
def _(c):
if c.transaction_manager is not None:
c.transaction_manager.abort()
c.afterCompletion = c.newTransaction = c.close = noop
c._release_resources()
def _(conn):
if conn.transaction_manager is not None:
for c in six.itervalues(conn.connections):
c.explicit_transactions = True
conn.transaction_manager.abort()
conn._release_resources()
self._mvcc_storage.close()
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