]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug in :class:`.Connection` and pool where the
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 4 Feb 2015 23:51:24 +0000 (18:51 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 4 Feb 2015 23:51:24 +0000 (18:51 -0500)
: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

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/pool.py
test/engine/test_reconnect.py
test/engine/test_transaction.py

index d1495274ac241cbc95aee440b35facfadd7fa7eb..a145ba259f1d3a16999635d344de5cf03e03f0c4 100644 (file)
 .. 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
index 8d6dd636ab84d67ea2d9ac2acff476172cbb3343..305fa4620f95d936b14c9e6a0b17bdd7a829915e 100644 (file)
@@ -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`
index 253bd77b801fea9fceb4778ea5d1e3fbf5926321..25db5d5ba1dd002bce58e705dbb2bac7e1dbfa8e 100644 (file)
@@ -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):
index 4500ada6a02b0d13740fa2781f3e20e9d09404e7..61931969368d07fbdaee658e5054b206a9204b81 100644 (file)
@@ -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()
 
index b7d9009175475b8e487140ebf751484decf4a3c9..b662c7fcd941a832edeefaf75ee44b49b2766383 100644 (file)
@@ -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(