Erlend E. Aasland <erlend.aasl...@innova.no> added the comment:

> I believe the reason for this problem is that the exception happened in the
> implicit `commit` that is run on exiting the context manager, rather than
> inside it. In fact the exception is in the `pass` line rather than in the
> `execute` line. This exception did not trigger a `rollback` because the it
> happened after `pysqlite_connection_exit` checks for exceptions.

FYI, here's the SQLite API interaction from the context manager, 
chronologically (using the test from the PR). (I only show the relevant 
arguments passed to the API, for readability.)

sqlite3_prepare_v2("insert into t values('test')", insert_stmt) => SQLITE_OK
sqlite3_get_autocommit()
# Note, the insert statement is now prepared, but not executed yet.

# Transaction control now begins
sqlite3_prepare_v2("BEGIN ", begin_stmt) => SQLITE_OK
sqlite3_step(begin_stmt) => SQLITE_DONE
sqlite3_finalize(begin_stmt)

# Here, the insert statement is executed
sqlite3_bind_blob_parameter_count(insert_stmt)
sqlite3_step(insert_stmt) => SQLITE_DONE
sqlite3_changes()
sqlite3_last_insert_rowid()
sqlite3_reset(insert_stmt) => SQLITE_OK
sqlite3_get_autocommit()

# Enter __exit__: no exception has been raised, so it tries to commit
sqlite3_prepare_v2("commit", commit_stmt) => SQLITE_OK
sqlite3_step(commit_stmt) => SQLITE_BUSY (database is locked)
sqlite3_finalize(commit_stmt)

# After the fix, rollback is now executed
sqlite3_prepare_v2("rollback", rollback_stmt)
sqlite3_step(rollback_stmt) => SQLITE_DONE
sqlite3_finalize(rollback_Stmt)


As you can see, it does not fail (and raise an exception) until commit is 
issued inside __exit__.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue27334>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to