summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-02-04 18:51:24 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2015-02-04 18:51:24 -0500
commit068f9a1531c8114360d5fcd964c27fe6a21f4679 (patch)
tree3eb3a1a85af928f792c4de42d1d16520ec4575a7
parent9cbe235810b7c0c24d2556b4bb581b0207812e2d (diff)
downloadsqlalchemy-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.rst11
-rw-r--r--lib/sqlalchemy/engine/base.py7
-rw-r--r--lib/sqlalchemy/pool.py1
-rw-r--r--test/engine/test_reconnect.py10
-rw-r--r--test/engine/test_transaction.py12
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(