You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For sqlite backend, when inside a transaction, errors are raised at the execution of the COMMIT statement instead of the SQL that causes the error, for example
the _transaction_stack.pop() is called before the _transaction.commit() is called, so if _transaction.commit() raised an error, the current transaction is lost in the connection and cannot be rolled back, thus leading the database to be locked;
Fix
To prevent this problem, I came up with a workaround:
to catch errors in commit() and call rollback() manually
move the _transaction_stack.pop() after the commit() statement, so the transaction will be poped after committed successfully
namely:
fromdatabases.coreimportTransactionclass_Transaction(Transaction):
asyncdefcommit(self) ->None:
asyncwithself._connection._transaction_lock:
assertself._connection._transaction_stack[-1] isselfassertself._transactionisnotNoneawaitself._transaction.commit()
# POP after committing successfullyself._connection._transaction_stack.pop()
awaitself._connection.__aexit__()
self._transaction=Noneasyncdef__aexit__(self, exc_type, exc_value, traceback):
""" Called when exiting `async with database.transaction()` """ifexc_typeisnotNoneorself._force_rollback:
awaitself.rollback()
else:
try:
awaitself.commit()
exceptExceptionase:
awaitself.rollback()
raisee
I am following the contributing guide here to submit an issue to discuss this modification before I make a pull request, and hope this can be merged to the repo soon
The text was updated successfully, but these errors were encountered:
Context
For
sqlite
backend, when inside a transaction, errors are raised at the execution of theCOMMIT
statement instead of the SQL that causes the error, for exampleIt was line 3 causing the
SQLITE_CONSTRAINT_FOREIGNKEY
error, but the error is raised during theCOMMIT
execution;Problem
in
databases/core.py
line 463:the
_transaction_stack.pop()
is called before the_transaction.commit()
is called, so if_transaction.commit()
raised an error, the current transaction is lost in the connection and cannot be rolled back, thus leading the database to be locked;Fix
To prevent this problem, I came up with a workaround:
commit()
and callrollback()
manually_transaction_stack.pop()
after thecommit()
statement, so the transaction will be poped after committed successfullynamely:
I am following the contributing guide here to submit an issue to discuss this modification before I make a pull request, and hope this can be merged to the repo soon
The text was updated successfully, but these errors were encountered: