From 576b9993879988b1df4a04cd5baadf71912e9fcb Mon Sep 17 00:00:00 2001 From: zah Date: Wed, 5 Oct 2022 01:40:46 +0300 Subject: [PATCH] Handle Sqlite automatic rollbacks gracefully (#3996) --- beacon_chain/beacon_chain_db.nim | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/beacon_chain/beacon_chain_db.nim b/beacon_chain/beacon_chain_db.nim index 00342c072..d06305580 100644 --- a/beacon_chain/beacon_chain_db.nim +++ b/beacon_chain/beacon_chain_db.nim @@ -400,7 +400,23 @@ template withManyWrites*(dbParam: BeaconChainDB, body: untyped) = if commit: expectDb db.db.exec("COMMIT TRANSACTION;") else: - expectDb db.db.exec("ROLLBACK TRANSACTION;") + # https://www.sqlite.org/lang_transaction.html + # + # For all of these errors, SQLite attempts to undo just the one statement + # it was working on and leave changes from prior statements within the same + # transaction intact and continue with the transaction. However, depending + # on the statement being evaluated and the point at which the error occurs, + # it might be necessary for SQLite to rollback and cancel the entire transaction. + # An application can tell which course of action SQLite took by using the + # sqlite3_get_autocommit() C-language interface. + # + # It is recommended that applications respond to the errors listed above by + # explicitly issuing a ROLLBACK command. If the transaction has already been + # rolled back automatically by the error response, then the ROLLBACK command + # will fail with an error, but no harm is caused by this. + # + if isInsideTransaction(db.db): # calls `sqlite3_get_autocommit` + expectDb db.db.exec("ROLLBACK TRANSACTION;") proc new*(T: type BeaconChainDB, dir: string,