From bff788eb564ca4eb50afde8b15aa50aa5fbb2e96 Mon Sep 17 00:00:00 2001 From: antao Date: Tue, 20 Dec 2022 23:53:07 +0800 Subject: [PATCH 1/3] Add setAutoCommit method to the Transaction class --- orm_lib/inc/drogon/orm/DbClient.h | 8 ++- orm_lib/src/TransactionImpl.cc | 84 ++++++++++++++++++++++++++----- orm_lib/src/TransactionImpl.h | 10 ++-- 3 files changed, 86 insertions(+), 16 deletions(-) diff --git a/orm_lib/inc/drogon/orm/DbClient.h b/orm_lib/inc/drogon/orm/DbClient.h index 5bcb0e0f74..86089d607e 100644 --- a/orm_lib/inc/drogon/orm/DbClient.h +++ b/orm_lib/inc/drogon/orm/DbClient.h @@ -362,10 +362,16 @@ class Transaction : public DbClient { public: virtual void rollback() = 0; - // virtual void commit() = 0; + virtual void commit(std::function commitCallback) = 0; virtual void setCommitCallback( const std::function &commitCallback) = 0; + /** + * @pref auto-commit or auto-rollback when the transaction object is + * destroyed; the default behavior is to commit. + */ + virtual void setAutoCommit(bool) = 0; + void closeAll() override { } diff --git a/orm_lib/src/TransactionImpl.cc b/orm_lib/src/TransactionImpl.cc index 0f55142400..8cba1926f0 100644 --- a/orm_lib/src/TransactionImpl.cc +++ b/orm_lib/src/TransactionImpl.cc @@ -41,25 +41,26 @@ TransactionImpl::~TransactionImpl() auto loop = connectionPtr_->loop(); loop->queueInLoop([conn = connectionPtr_, ucb = std::move(usedUpCallback_), - commitCb = std::move(commitCallback_)]() { + commitCb = std::move(commitCallback_), + autoCommit = autoCommit_]() { conn->setIdleCallback([ucb = std::move(ucb)]() { if (ucb) ucb(); }); conn->execSql( - "commit", + autoCommit ? "commit" : "rollback", 0, {}, {}, {}, - [commitCb](const Result &) { + [commitCb, autoCommit](const Result &) { LOG_TRACE << "Transaction committed!"; - if (commitCb) + if (autoCommit && commitCb) { commitCb(true); } }, - [commitCb](const std::exception_ptr &ePtr) { + [commitCb, autoCommit](const std::exception_ptr &ePtr) { try { std::rethrow_exception(ePtr); @@ -68,7 +69,7 @@ TransactionImpl::~TransactionImpl() { LOG_ERROR << "Transaction submission failed:" << e.base().what(); - if (commitCb) + if (autoCommit && commitCb) { commitCb(false); } @@ -149,7 +150,68 @@ void TransactionImpl::execSqlInLoop( exceptCallback(exceptPtr); } } - +void TransactionImpl::commit(std::function callback) +{ + auto thisPtr = shared_from_this(); + if (callback) + { + commitCallback_ = std::move(callback); + } + loop_->runInLoop([thisPtr]() { + if (thisPtr->isCommitedOrRolledback_) + return; + if (thisPtr->isWorking_) + { + // push sql cmd to buffer; + auto cmdPtr = std::make_shared(); + cmdPtr->sql_ = "commit"; + cmdPtr->parametersNumber_ = 0; + cmdPtr->callback_ = [thisPtr](const Result &) { + LOG_DEBUG << "Transaction commit!"; + thisPtr->isCommitedOrRolledback_ = true; + if (thisPtr->commitCallback_) + { + thisPtr->commitCallback_(true); + } + }; + cmdPtr->exceptionCallback_ = [thisPtr](const std::exception_ptr &) { + thisPtr->isCommitedOrRolledback_ = true; + if (thisPtr->commitCallback_) + { + thisPtr->commitCallback_(false); + } + LOG_ERROR << "Transaction commit error"; + }; + cmdPtr->isRollbackOrCommitCmd_ = true; + thisPtr->sqlCmdBuffer_.push_back(std::move(cmdPtr)); + return; + } + thisPtr->isWorking_ = true; + thisPtr->thisPtr_ = thisPtr; + thisPtr->connectionPtr_->execSql( + "commit", + 0, + {}, + {}, + {}, + [thisPtr](const Result &) { + LOG_TRACE << "Transaction commit!"; + thisPtr->isCommitedOrRolledback_ = true; + if (thisPtr->commitCallback_) + { + thisPtr->commitCallback_(true); + } + }, + [thisPtr](const std::exception_ptr &) { + LOG_ERROR << "Transaction commit error"; + thisPtr->isCommitedOrRolledback_ = true; + if (thisPtr->commitCallback_) + { + thisPtr->commitCallback_(false); + } + }); + }); +} void TransactionImpl::rollback() { auto thisPtr = shared_from_this(); @@ -172,7 +234,7 @@ void TransactionImpl::rollback() thisPtr->isCommitedOrRolledback_ = true; LOG_ERROR << "Transaction roll back error"; }; - cmdPtr->isRollbackCmd_ = true; + cmdPtr->isRollbackOrCommitCmd_ = true; // Rollback cmd should be executed firstly, so we push it in front // of the list thisPtr->sqlCmdBuffer_.push_front(std::move(cmdPtr)); @@ -189,10 +251,8 @@ void TransactionImpl::rollback() [thisPtr](const Result &) { LOG_TRACE << "Transaction roll back!"; thisPtr->isCommitedOrRolledback_ = true; - // clearupCb(); }, [thisPtr](const std::exception_ptr &) { - // clearupCb(); LOG_ERROR << "Transaction roll back error"; thisPtr->isCommitedOrRolledback_ = true; }); @@ -220,7 +280,7 @@ void TransactionImpl::execNewTask() std::move(cmd->formats_), [callback = std::move(cmd->callback_), cmd, thisPtr]( const Result &r) { - if (cmd->isRollbackCmd_) + if (cmd->isRollbackOrCommitCmd_) { thisPtr->isCommitedOrRolledback_ = true; } @@ -228,7 +288,7 @@ void TransactionImpl::execNewTask() callback(r); }, [cmd, thisPtr](const std::exception_ptr &ePtr) { - if (!cmd->isRollbackCmd_) + if (!cmd->isRollbackOrCommitCmd_) thisPtr->rollback(); else { diff --git a/orm_lib/src/TransactionImpl.h b/orm_lib/src/TransactionImpl.h index 0be310f5c0..8a7c096dd8 100644 --- a/orm_lib/src/TransactionImpl.h +++ b/orm_lib/src/TransactionImpl.h @@ -49,10 +49,14 @@ class TransactionImpl : public Transaction, { timeout_ = timeout; } - + void setAutoCommit(bool autoCommit) override + { + autoCommit_ = autoCommit; + } + void commit(std::function callback) override; private: DbConnectionPtr connectionPtr_; - + bool autoCommit_{true}; void execSql(const char *sql, size_t sqlLength, size_t paraNum, @@ -139,7 +143,7 @@ class TransactionImpl : public Transaction, std::vector formats_; QueryCallback callback_; ExceptPtrCallback exceptionCallback_; - bool isRollbackCmd_{false}; + bool isRollbackOrCommitCmd_{false}; std::shared_ptr thisPtr_; }; From 589e573b9105edf4312f402a4ea78ce4d00c260e Mon Sep 17 00:00:00 2001 From: antao Date: Wed, 21 Dec 2022 09:20:23 +0800 Subject: [PATCH 2/3] Lint --- orm_lib/src/TransactionImpl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/orm_lib/src/TransactionImpl.h b/orm_lib/src/TransactionImpl.h index 8a7c096dd8..04b2a07c7b 100644 --- a/orm_lib/src/TransactionImpl.h +++ b/orm_lib/src/TransactionImpl.h @@ -54,6 +54,7 @@ class TransactionImpl : public Transaction, autoCommit_ = autoCommit; } void commit(std::function callback) override; + private: DbConnectionPtr connectionPtr_; bool autoCommit_{true}; From 0cee17387052c568ddb33817e405434d05844090 Mon Sep 17 00:00:00 2001 From: an-tao Date: Tue, 28 Nov 2023 18:28:37 +0800 Subject: [PATCH 3/3] Lint --- orm_lib/src/TransactionImpl.cc | 2 ++ orm_lib/src/TransactionImpl.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/orm_lib/src/TransactionImpl.cc b/orm_lib/src/TransactionImpl.cc index 8cba1926f0..13467b64de 100644 --- a/orm_lib/src/TransactionImpl.cc +++ b/orm_lib/src/TransactionImpl.cc @@ -150,6 +150,7 @@ void TransactionImpl::execSqlInLoop( exceptCallback(exceptPtr); } } + void TransactionImpl::commit(std::function callback) { auto thisPtr = shared_from_this(); @@ -212,6 +213,7 @@ void TransactionImpl::commit(std::function callback) }); }); } + void TransactionImpl::rollback() { auto thisPtr = shared_from_this(); diff --git a/orm_lib/src/TransactionImpl.h b/orm_lib/src/TransactionImpl.h index 04b2a07c7b..d6df251c25 100644 --- a/orm_lib/src/TransactionImpl.h +++ b/orm_lib/src/TransactionImpl.h @@ -49,15 +49,18 @@ class TransactionImpl : public Transaction, { timeout_ = timeout; } + void setAutoCommit(bool autoCommit) override { autoCommit_ = autoCommit; } + void commit(std::function callback) override; private: DbConnectionPtr connectionPtr_; bool autoCommit_{true}; + void execSql(const char *sql, size_t sqlLength, size_t paraNum,