ensure_autocommit_on() raises TransactionError inside a transaction

Assigning conn.isolation_level commits any pending transaction as a side
effect, so entering the context manager with a transaction open silently
committed the caller's work and made a later rollback() a no-op. All
internal callers already ensure no transaction is open; the public API
now enforces it, matching enable_wal() and disable_wal().

Refs https://github.com/simonw/sqlite-utils/issues/769#issuecomment-4900034150

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Simon Willison 2026-07-06 21:51:31 -07:00
commit a0387791e5
3 changed files with 27 additions and 0 deletions

View file

@ -665,7 +665,16 @@ class Database:
# do stuff here
The previous ``isolation_level`` is restored at the end of the block.
:raises TransactionError: if a transaction is open - assigning
``isolation_level`` would commit it as a side effect, silently
breaking the caller's ability to roll back
"""
if self.conn.in_transaction:
raise TransactionError(
"ensure_autocommit_on() cannot be used inside a transaction - "
"changing isolation_level would commit the open transaction"
)
old_isolation_level = self.conn.isolation_level
try:
self.conn.isolation_level = None