diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-02-04 18:51:24 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-02-04 18:51:24 -0500 |
commit | 068f9a1531c8114360d5fcd964c27fe6a21f4679 (patch) | |
tree | 3eb3a1a85af928f792c4de42d1d16520ec4575a7 | |
parent | 9cbe235810b7c0c24d2556b4bb581b0207812e2d (diff) | |
download | sqlalchemy-068f9a1531c8114360d5fcd964c27fe6a21f4679.tar.gz |
- 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
-rw-r--r-- | doc/build/changelog/changelog_09.rst | 11 | ||||
-rw-r--r-- | lib/sqlalchemy/engine/base.py | 7 | ||||
-rw-r--r-- | lib/sqlalchemy/pool.py | 1 | ||||
-rw-r--r-- | test/engine/test_reconnect.py | 10 | ||||
-rw-r--r-- | test/engine/test_transaction.py | 12 |
5 files changed, 41 insertions, 0 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index d1495274a..a145ba259 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -15,6 +15,17 @@ :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 8d6dd636a..305fa4620 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 253bd77b8..25db5d5ba 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 4500ada6a..619319693 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 b7d900917..b662c7fcd 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( |