Skip to content

Commit 472d2ca

Browse files
committed
sqlite: introduce HasActiveTxn method
Util function to clean up code and let us verify, in the following-up commit, that dangling, to-be-reverted db transactions cannot occur anymore.
1 parent dca874e commit 472d2ca

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

src/wallet/sqlite.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,12 @@ void SQLiteDatabase::Close()
377377
m_db = nullptr;
378378
}
379379

380+
bool SQLiteDatabase::HasActiveTxn()
381+
{
382+
// 'sqlite3_get_autocommit' returns true by default, and false if a transaction has begun and not been committed or rolled back.
383+
return m_db && sqlite3_get_autocommit(m_db) == 0;
384+
}
385+
380386
int SQliteExecHandler::Exec(SQLiteDatabase& database, const std::string& statement)
381387
{
382388
return sqlite3_exec(database.m_db, statement.data(), nullptr, nullptr, nullptr);
@@ -399,8 +405,8 @@ SQLiteBatch::SQLiteBatch(SQLiteDatabase& database)
399405

400406
void SQLiteBatch::Close()
401407
{
402-
// If m_db is in a transaction (i.e. not in autocommit mode), then abort the transaction in progress
403-
if (m_database.m_db && sqlite3_get_autocommit(m_database.m_db) == 0) {
408+
// If we began a transaction, and it wasn't committed, abort the transaction in progress
409+
if (m_database.HasActiveTxn()) {
404410
if (TxnAbort()) {
405411
LogPrintf("SQLiteBatch: Batch closed unexpectedly without the transaction being explicitly committed or aborted\n");
406412
} else {
@@ -611,7 +617,7 @@ std::unique_ptr<DatabaseCursor> SQLiteBatch::GetNewPrefixCursor(Span<const std::
611617

612618
bool SQLiteBatch::TxnBegin()
613619
{
614-
if (!m_database.m_db || sqlite3_get_autocommit(m_database.m_db) == 0) return false;
620+
if (!m_database.m_db || m_database.HasActiveTxn()) return false;
615621
int res = Assert(m_exec_handler)->Exec(m_database, "BEGIN TRANSACTION");
616622
if (res != SQLITE_OK) {
617623
LogPrintf("SQLiteBatch: Failed to begin the transaction\n");
@@ -621,7 +627,7 @@ bool SQLiteBatch::TxnBegin()
621627

622628
bool SQLiteBatch::TxnCommit()
623629
{
624-
if (!m_database.m_db || sqlite3_get_autocommit(m_database.m_db) != 0) return false;
630+
if (!m_database.HasActiveTxn()) return false;
625631
int res = Assert(m_exec_handler)->Exec(m_database, "COMMIT TRANSACTION");
626632
if (res != SQLITE_OK) {
627633
LogPrintf("SQLiteBatch: Failed to commit the transaction\n");
@@ -631,7 +637,7 @@ bool SQLiteBatch::TxnCommit()
631637

632638
bool SQLiteBatch::TxnAbort()
633639
{
634-
if (!m_database.m_db || sqlite3_get_autocommit(m_database.m_db) != 0) return false;
640+
if (!m_database.HasActiveTxn()) return false;
635641
int res = Assert(m_exec_handler)->Exec(m_database, "ROLLBACK TRANSACTION");
636642
if (res != SQLITE_OK) {
637643
LogPrintf("SQLiteBatch: Failed to abort the transaction\n");

src/wallet/sqlite.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ class SQLiteDatabase : public WalletDatabase
154154
/** Make a SQLiteBatch connected to this database */
155155
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
156156

157+
/** Return true if there is an on-going txn in this connection */
158+
bool HasActiveTxn();
159+
157160
sqlite3* m_db{nullptr};
158161
bool m_use_unsafe_sync;
159162
};

0 commit comments

Comments
 (0)