If SQLite commit() fails, transaction status gets incorrectly cleared
Bug #136771 reported by
Richard Boulton
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Storm |
Fix Released
|
Undecided
|
Gustavo Niemeyer | ||
pysqlite |
Won't Fix
|
Unknown
|
Bug Description
If a commit() call in SQLIte fails, for example, because another connection is keeping a lock on the database, subsequent calls to the connection fail with "OperationalError: cannot start a transaction within a transaction". This appears to be because the SQLiteConnectio
Also, the commit() call doesn't respect the timeout setting - it fails immediately.
The sqlite-
Related branches
description: | updated |
Changed in pysqlite: | |
importance: | Undecided → Unknown |
status: | New → Unknown |
Changed in pysqlite: | |
status: | Unknown → New |
Changed in storm: | |
status: | Fix Committed → Fix Released |
Changed in pysqlite: | |
status: | New → Won't Fix |
To post a comment you must log in.
After looking into the state in which the database is left after a commit() fails more closely, I believe that the connection is only left in a state in which COMMIT can be retried if the failure was due to the database being locked. In all other cases, the transaction is rolled back, and the connection is no longer in the middle of a transaction. My proposed fix assumed that any failure left the transaction open.
According to http:// www.sqlite. org/lang_ transaction. html the "database locked" case can be detected by the SQLITE_BUSY return code. pysqlite2 converts this to the "database is locked" OperationalError, and after reading through the code, I believe no other case will have this message. Therefore, we can detect this case, and set the SQLiteConnectio n._in_transacti on member to False in all other cases.
I've pushed changes to implement this to the sqlite- locked- recovery branch.