Don't manipulate Connection state after it has been returned to the pool.

Doing so leads to race conditions.

In particular, there can be an AttributeError.

See https://github.com/zodb/zodbshootout/issues/26 for details.
parent f3b2350a
......@@ -10,6 +10,11 @@
See `issue 139 <https://github.com/zopefoundation/ZODB/issues/139`_.
- ``persistent`` is no longer required at setup time.
See `issue 119 <https://github.com/zopefoundation/ZODB/issues/119>`_.
- ``Connection.close`` and ``Connection.open`` no longer race on
``self.transaction_manager``, which could lead to
``AttributeError``. This was a bug introduced in 5.0.1. See `issue
142 <https://github.com/zopefoundation/ZODB/pull/143>`_.
5.1.1 (2016-11-18)
==================
......
......@@ -304,6 +304,14 @@ class Connection(ExportImport, object):
# closed the DB already, .e.g, ZODB.connection() does this.
self.transaction_manager.unregisterSynch(self)
am = self._db._activity_monitor
if am is not None:
am.closedConnection(self)
# Drop transaction manager to release resources and help prevent errors
self.transaction_manager = None
if primary:
for connection in self.connections.values():
if connection is not self:
......@@ -320,12 +328,9 @@ class Connection(ExportImport, object):
else:
self.opened = None
am = self._db._activity_monitor
if am is not None:
am.closedConnection(self)
# We may have been reused by another thread at this point so
# we can't manipulate or check the state of `self` any more.
# Drop transaction manager to release resources and help prevent errors
self.transaction_manager = None
def db(self):
"""Returns a handle to the database this connection belongs to."""
......
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