--- /dev/null
+.. 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.
)
def _is_autocommit_isolation(self) -> bool:
+ opt_iso = self._execution_options.get("isolation_level", None)
return bool(
- self._execution_options.get("isolation_level", None)
- == "AUTOCOMMIT"
+ opt_iso == "AUTOCOMMIT"
+ or (
+ opt_iso is None
+ and self.engine.dialect._on_connect_isolation_level
+ == "AUTOCOMMIT"
+ )
)
def get_transaction(self) -> Optional[RootTransaction]:
def _begin_impl(self, transaction: RootTransaction) -> None:
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
"""
+ # NOTE: this does not take into effect engine-level isolation level.
+ # not clear if this should be changed, seems like it should
default_isolation_level: Optional[_IsolationLevel]
"""the isolation that is implicitly present on new connections"""
+ # create_engine() -> isolation_level currently goes here
+ _on_connect_isolation_level: Optional[_IsolationLevel]
+
execution_ctx_cls: Type["ExecutionContext"]
"""a :class:`.ExecutionContext` class used to handle statement execution"""
e.connect().close()
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,
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
):
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",
]
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",
]