From: Mike Bayer Date: Wed, 4 Feb 2015 23:51:24 +0000 (-0500) Subject: - Fixed bug in :class:`.Connection` and pool where the X-Git-Tag: rel_1_0_0b1~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=068f9a1531c8114360d5fcd964c27fe6a21f4679;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixed bug in :class:`.Connection` and pool where the :meth:`.Connection.invalidate` method, or an invalidation due to a database disconnect, would fail if the ``isolation_level`` parameter had been used with :meth:`.Connection.execution_options`; the "finalizer" that resets the isolation level would be called on the no longer opened connection. fixes #3302 --- diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index d1495274ac..a145ba259f 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -14,6 +14,17 @@ .. changelog:: :version: 0.9.9 + .. change:: + :tags: bug, engine + :tickets: 3302 + + Fixed bug in :class:`.Connection` and pool where the + :meth:`.Connection.invalidate` method, or an invalidation due + to a database disconnect, would fail if the + ``isolation_level`` parameter had been used with + :meth:`.Connection.execution_options`; the "finalizer" that resets + the isolation level would be called on the no longer opened connection. + .. change:: :tags: feature, orm :tickets: 3296 diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 8d6dd636ab..305fa4620f 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -235,6 +235,13 @@ class Connection(Connectable): transaction has been started with :meth:`.Connection.begin` or similar. + .. note:: The ``isolation_level`` execution option is implicitly + reset if the :class:`.Connection` is invalidated, e.g. via + the :meth:`.Connection.invalidate` method, or if a + disconnection error occurs. The new connection produced after + the invalidation will not have the isolation level re-applied + to it automatically. + .. seealso:: :paramref:`.create_engine.isolation_level` diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 253bd77b80..25db5d5ba1 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -529,6 +529,7 @@ class _ConnectionRecord(object): return self.connection def __close(self): + self.finalize_callback.clear() self.__pool._close_connection(self.connection) def __connect(self): diff --git a/test/engine/test_reconnect.py b/test/engine/test_reconnect.py index 4500ada6a0..6193196936 100644 --- a/test/engine/test_reconnect.py +++ b/test/engine/test_reconnect.py @@ -5,6 +5,7 @@ from sqlalchemy import ( from sqlalchemy.testing.schema import Table, Column import sqlalchemy as tsa from sqlalchemy import testing +from sqlalchemy.testing import mock from sqlalchemy.testing import engines from sqlalchemy.testing import fixtures from sqlalchemy.testing.engines import testing_engine @@ -211,6 +212,15 @@ class MockReconnectTest(fixtures.TestBase): [[call()], []] ) + def test_invalidate_dont_call_finalizer(self): + conn = self.db.connect() + finalizer = mock.Mock() + conn.connection._connection_record.\ + finalize_callback.append(finalizer) + conn.invalidate() + assert conn.invalidated + eq_(finalizer.call_count, 0) + def test_conn_reusable(self): conn = self.db.connect() diff --git a/test/engine/test_transaction.py b/test/engine/test_transaction.py index b7d9009175..b662c7fcd9 100644 --- a/test/engine/test_transaction.py +++ b/test/engine/test_transaction.py @@ -1323,6 +1323,18 @@ class IsolationLevelTest(fixtures.TestBase): eng.connect ) + def test_connection_invalidated(self): + eng = testing_engine() + conn = eng.connect() + c2 = conn.execution_options( + isolation_level=self._non_default_isolation_level()) + c2.invalidate() + c2.connection + + # TODO: do we want to rebuild the previous isolation? + # for now, this is current behavior so we will leave it. + eq_(c2.get_isolation_level(), self._default_isolation_level()) + def test_per_connection(self): from sqlalchemy.pool import QueuePool eng = testing_engine(