summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-03-24 13:58:20 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-03-24 14:03:08 -0400
commit4ccf8b72147496a033ef0c517bcf7345c516b3e8 (patch)
tree174b710e10adf37925089b5d9f2efe1c772c8392
parent4679251d195889b420c5f8709995cfc97b6d25d7 (diff)
downloadsqlalchemy-4ccf8b72147496a033ef0c517bcf7345c516b3e8.tar.gz
more autocommit messaging
Further clarified connection-level logging to indicate the BEGIN, ROLLBACK and COMMIT log messages do not actually indicate a real transaction when the AUTOCOMMIT isolation level is in use; messaging has been extended to include the BEGIN message itself, and the messaging has also been fixed to accommodate when the :class:`.Engine` level :paramref:`.create_engine.isolation_level` parameter was used directly. Fixes: #7853 Change-Id: Iafc78070737ad117f84262e4bde84b81a81e4ea1 (cherry picked from commit 56366924673f88e51c74d94058c11132a057ecfa)
-rw-r--r--doc/build/changelog/unreleased_14/7853.rst10
-rw-r--r--lib/sqlalchemy/engine/base.py27
-rw-r--r--test/engine/test_logging.py45
3 files changed, 72 insertions, 10 deletions
diff --git a/doc/build/changelog/unreleased_14/7853.rst b/doc/build/changelog/unreleased_14/7853.rst
new file mode 100644
index 000000000..66856c29e
--- /dev/null
+++ b/doc/build/changelog/unreleased_14/7853.rst
@@ -0,0 +1,10 @@
+.. change::
+ :tags: bug, engine
+ :tickets: 7853
+
+ Further clarified connection-level logging to indicate the BEGIN, ROLLBACK
+ and COMMIT log messages do not actually indicate a real transaction when
+ the AUTOCOMMIT isolation level is in use; messaging has been extended to
+ include the BEGIN message itself, and the messaging has also been fixed to
+ accommodate when the :class:`.Engine` level
+ :paramref:`.create_engine.isolation_level` parameter was used directly.
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index cf6a14728..b5a3096e5 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -905,10 +905,15 @@ class Connection(Connectable):
and self._nested_transaction.is_active
)
- def _is_autocommit(self):
- return (
- self._execution_options.get("isolation_level", None)
- == "AUTOCOMMIT"
+ def _is_autocommit_isolation(self):
+ opt_iso = self._execution_options.get("isolation_level", None)
+ return bool(
+ opt_iso == "AUTOCOMMIT"
+ or (
+ opt_iso is None
+ and getattr(self.engine.dialect, "isolation_level", None)
+ == "AUTOCOMMIT"
+ )
)
def get_transaction(self):
@@ -939,7 +944,13 @@ class Connection(Connectable):
assert not self.__branch_from
if self._echo:
- self._log_info("BEGIN (implicit)")
+ if self._is_autocommit_isolation():
+ self._log_info(
+ "BEGIN (implicit; DBAPI should not BEGIN due to "
+ "autocommit mode)"
+ )
+ else:
+ self._log_info("BEGIN (implicit)")
self.__in_begin = True
@@ -961,7 +972,7 @@ class Connection(Connectable):
if self._still_open_and_dbapi_connection_is_valid:
if self._echo:
- if self._is_autocommit():
+ if self._is_autocommit_isolation():
self._log_info(
"ROLLBACK using DBAPI connection.rollback(), "
"DBAPI should ignore due to autocommit mode"
@@ -980,7 +991,7 @@ class Connection(Connectable):
# if a connection has this set as the isolation level, we can skip
# the "autocommit" warning as the operation will do "autocommit"
# in any case
- if autocommit and not self._is_autocommit():
+ if autocommit and not self._is_autocommit_isolation():
util.warn_deprecated_20(
"The current statement is being autocommitted using "
"implicit autocommit, which will be removed in "
@@ -993,7 +1004,7 @@ class Connection(Connectable):
self.dispatch.commit(self)
if self._echo:
- if self._is_autocommit():
+ if self._is_autocommit_isolation():
self._log_info(
"COMMIT using DBAPI connection.commit(), "
"DBAPI should ignore due to autocommit mode"
diff --git a/test/engine/test_logging.py b/test/engine/test_logging.py
index 806336368..7a0ed6e79 100644
--- a/test/engine/test_logging.py
+++ b/test/engine/test_logging.py
@@ -641,6 +641,13 @@ class TransactionContextLoggingTest(fixtures.TestBase):
return e
@testing.fixture()
+ def autocommit_iso_logging_engine(self, testing_engine):
+ kw = {"echo": True, "future": True, "isolation_level": "AUTOCOMMIT"}
+ e = testing_engine(options=kw)
+ e.connect().close()
+ return e
+
+ @testing.fixture()
def plain_logging_engine(self, testing_engine):
# deliver an engine with logging using the plain logging API,
# not the echo parameter
@@ -675,6 +682,38 @@ class TransactionContextLoggingTest(fixtures.TestBase):
assert_buf(["BEGIN (implicit)", "ROLLBACK"])
+ def test_commit_as_you_go_block_commit_engine_level_autocommit(
+ self, autocommit_iso_logging_engine, assert_buf
+ ):
+ with autocommit_iso_logging_engine.connect() as conn:
+ conn.begin()
+ conn.commit()
+
+ assert_buf(
+ [
+ "BEGIN (implicit; DBAPI should not "
+ "BEGIN due to autocommit mode)",
+ "COMMIT using DBAPI connection.commit(), DBAPI "
+ "should ignore due to autocommit mode",
+ ]
+ )
+
+ def test_commit_engine_level_autocommit_exec_opt_nonauto(
+ self, autocommit_iso_logging_engine, assert_buf
+ ):
+ with autocommit_iso_logging_engine.execution_options(
+ isolation_level=testing.db.dialect.default_isolation_level
+ ).connect() as conn:
+ conn.begin()
+ conn.commit()
+
+ assert_buf(
+ [
+ "BEGIN (implicit)",
+ "COMMIT",
+ ]
+ )
+
def test_commit_as_you_go_block_commit_autocommit(
self, logging_engine, assert_buf
):
@@ -686,7 +725,8 @@ class TransactionContextLoggingTest(fixtures.TestBase):
assert_buf(
[
- "BEGIN (implicit)",
+ "BEGIN (implicit; DBAPI should not "
+ "BEGIN due to autocommit mode)",
"COMMIT using DBAPI connection.commit(), DBAPI "
"should ignore due to autocommit mode",
]
@@ -703,7 +743,8 @@ class TransactionContextLoggingTest(fixtures.TestBase):
assert_buf(
[
- "BEGIN (implicit)",
+ "BEGIN (implicit; DBAPI should not "
+ "BEGIN due to autocommit mode)",
"ROLLBACK using DBAPI connection.rollback(), DBAPI "
"should ignore due to autocommit mode",
]