--- /dev/null
+.. change::
+ :tags: bug, engine
+ :tickets: 10147
+
+ Fixed critical issue where setting
+ :paramref:`_sa.create_engine.isolation_level` to ``AUTOCOMMIT`` (as opposed
+ to using the :meth:`_engine.Engine.execution_options` method) would fail to
+ restore "autocommit" to a pooled connection if an alternate isolation level
+ were temporarily selected using
+ :paramref:`_engine.Connection.execution_options.isolation_level`.
self.set_isolation_level(dbapi_conn, level)
def reset_isolation_level(self, dbapi_conn):
- # default_isolation_level is read from the first connection
- # after the initial set of 'isolation_level', if any, so is
- # the configured default of this dialect.
- self._assert_and_set_isolation_level(
- dbapi_conn, self.default_isolation_level
- )
+ if self._on_connect_isolation_level is not None:
+ assert (
+ self._on_connect_isolation_level == "AUTOCOMMIT"
+ or self._on_connect_isolation_level
+ == self.default_isolation_level
+ )
+ self._assert_and_set_isolation_level(
+ dbapi_conn, self._on_connect_isolation_level
+ )
+ else:
+ assert self.default_isolation_level is not None
+ self._assert_and_set_isolation_level(
+ dbapi_conn,
+ self.default_isolation_level,
+ )
def normalize_name(self, name):
if name is None:
):
eng.connect()
+ @testing.requires.independent_readonly_connections
+ def test_dialect_user_setting_is_restored(self, testing_engine):
+ levels = requirements.get_isolation_levels(config)
+ default = levels["default"]
+ supported = (
+ sorted(
+ set(levels["supported"]).difference([default, "AUTOCOMMIT"])
+ )
+ )[0]
+
+ e = testing_engine(options={"isolation_level": supported})
+
+ with e.connect() as conn:
+ eq_(conn.get_isolation_level(), supported)
+
+ with e.connect() as conn:
+ conn.execution_options(isolation_level=default)
+ eq_(conn.get_isolation_level(), default)
+
+ with e.connect() as conn:
+ eq_(conn.get_isolation_level(), supported)
+
class AutocommitIsolationTest(fixtures.TablesTest):
run_deletes = "each"
)
self._test_conn_autocommits(conn, False)
+ @testing.requires.independent_readonly_connections
+ @testing.variation("use_dialect_setting", [True, False])
+ def test_dialect_autocommit_is_restored(
+ self, testing_engine, use_dialect_setting
+ ):
+ """test #10147"""
+
+ if use_dialect_setting:
+ e = testing_engine(options={"isolation_level": "AUTOCOMMIT"})
+ else:
+ e = testing_engine().execution_options(
+ isolation_level="AUTOCOMMIT"
+ )
+
+ levels = requirements.get_isolation_levels(config)
+
+ default = levels["default"]
+
+ with e.connect() as conn:
+ self._test_conn_autocommits(conn, True)
+
+ with e.connect() as conn:
+ conn.execution_options(isolation_level=default)
+ self._test_conn_autocommits(conn, False)
+
+ with e.connect() as conn:
+ self._test_conn_autocommits(conn, True)
+
class EscapingTest(fixtures.TestBase):
@provide_metadata