mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-07-08 17:30:36 +02:00
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.
This commit is contained in:
@ -377,6 +377,12 @@ void SQLiteDatabase::Close()
|
|||||||
m_db = nullptr;
|
m_db = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SQLiteDatabase::HasActiveTxn()
|
||||||
|
{
|
||||||
|
// 'sqlite3_get_autocommit' returns true by default, and false if a transaction has begun and not been committed or rolled back.
|
||||||
|
return m_db && sqlite3_get_autocommit(m_db) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
int SQliteExecHandler::Exec(SQLiteDatabase& database, const std::string& statement)
|
int SQliteExecHandler::Exec(SQLiteDatabase& database, const std::string& statement)
|
||||||
{
|
{
|
||||||
return sqlite3_exec(database.m_db, statement.data(), nullptr, nullptr, nullptr);
|
return sqlite3_exec(database.m_db, statement.data(), nullptr, nullptr, nullptr);
|
||||||
@ -399,8 +405,8 @@ SQLiteBatch::SQLiteBatch(SQLiteDatabase& database)
|
|||||||
|
|
||||||
void SQLiteBatch::Close()
|
void SQLiteBatch::Close()
|
||||||
{
|
{
|
||||||
// If m_db is in a transaction (i.e. not in autocommit mode), then abort the transaction in progress
|
// If we began a transaction, and it wasn't committed, abort the transaction in progress
|
||||||
if (m_database.m_db && sqlite3_get_autocommit(m_database.m_db) == 0) {
|
if (m_database.HasActiveTxn()) {
|
||||||
if (TxnAbort()) {
|
if (TxnAbort()) {
|
||||||
LogPrintf("SQLiteBatch: Batch closed unexpectedly without the transaction being explicitly committed or aborted\n");
|
LogPrintf("SQLiteBatch: Batch closed unexpectedly without the transaction being explicitly committed or aborted\n");
|
||||||
} else {
|
} else {
|
||||||
@ -611,7 +617,7 @@ std::unique_ptr<DatabaseCursor> SQLiteBatch::GetNewPrefixCursor(Span<const std::
|
|||||||
|
|
||||||
bool SQLiteBatch::TxnBegin()
|
bool SQLiteBatch::TxnBegin()
|
||||||
{
|
{
|
||||||
if (!m_database.m_db || sqlite3_get_autocommit(m_database.m_db) == 0) return false;
|
if (!m_database.m_db || m_database.HasActiveTxn()) return false;
|
||||||
int res = Assert(m_exec_handler)->Exec(m_database, "BEGIN TRANSACTION");
|
int res = Assert(m_exec_handler)->Exec(m_database, "BEGIN TRANSACTION");
|
||||||
if (res != SQLITE_OK) {
|
if (res != SQLITE_OK) {
|
||||||
LogPrintf("SQLiteBatch: Failed to begin the transaction\n");
|
LogPrintf("SQLiteBatch: Failed to begin the transaction\n");
|
||||||
@ -621,7 +627,7 @@ bool SQLiteBatch::TxnBegin()
|
|||||||
|
|
||||||
bool SQLiteBatch::TxnCommit()
|
bool SQLiteBatch::TxnCommit()
|
||||||
{
|
{
|
||||||
if (!m_database.m_db || sqlite3_get_autocommit(m_database.m_db) != 0) return false;
|
if (!m_database.HasActiveTxn()) return false;
|
||||||
int res = Assert(m_exec_handler)->Exec(m_database, "COMMIT TRANSACTION");
|
int res = Assert(m_exec_handler)->Exec(m_database, "COMMIT TRANSACTION");
|
||||||
if (res != SQLITE_OK) {
|
if (res != SQLITE_OK) {
|
||||||
LogPrintf("SQLiteBatch: Failed to commit the transaction\n");
|
LogPrintf("SQLiteBatch: Failed to commit the transaction\n");
|
||||||
@ -631,7 +637,7 @@ bool SQLiteBatch::TxnCommit()
|
|||||||
|
|
||||||
bool SQLiteBatch::TxnAbort()
|
bool SQLiteBatch::TxnAbort()
|
||||||
{
|
{
|
||||||
if (!m_database.m_db || sqlite3_get_autocommit(m_database.m_db) != 0) return false;
|
if (!m_database.HasActiveTxn()) return false;
|
||||||
int res = Assert(m_exec_handler)->Exec(m_database, "ROLLBACK TRANSACTION");
|
int res = Assert(m_exec_handler)->Exec(m_database, "ROLLBACK TRANSACTION");
|
||||||
if (res != SQLITE_OK) {
|
if (res != SQLITE_OK) {
|
||||||
LogPrintf("SQLiteBatch: Failed to abort the transaction\n");
|
LogPrintf("SQLiteBatch: Failed to abort the transaction\n");
|
||||||
|
@ -154,6 +154,9 @@ public:
|
|||||||
/** Make a SQLiteBatch connected to this database */
|
/** Make a SQLiteBatch connected to this database */
|
||||||
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
|
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
|
||||||
|
|
||||||
|
/** Return true if there is an on-going txn in this connection */
|
||||||
|
bool HasActiveTxn();
|
||||||
|
|
||||||
sqlite3* m_db{nullptr};
|
sqlite3* m_db{nullptr};
|
||||||
bool m_use_unsafe_sync;
|
bool m_use_unsafe_sync;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user