diff options
author | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2010-10-30 10:54:27 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2010-10-30 12:51:31 +0200 |
commit | 6129e5bf1fe0128eb7742a7270e1264b65798bbb (patch) | |
tree | f54afc81e8dcc0d14a13721170f497f8e2df6d2b /src/dal | |
parent | e4713d0203311fdfcfef72ae5632782075159a56 (diff) | |
download | manaserv-6129e5bf1fe0128eb7742a7270e1264b65798bbb.tar.gz manaserv-6129e5bf1fe0128eb7742a7270e1264b65798bbb.tar.xz manaserv-6129e5bf1fe0128eb7742a7270e1264b65798bbb.zip |
Have the PerformTransaction class automatically handle nesting
No need to fiddle around with "startTransaction" booleans now that the
helper class is a little more intelligent. When the database is already
performing a transaction, no new one will be started.
Diffstat (limited to 'src/dal')
-rw-r--r-- | src/dal/dataprovider.cpp | 15 | ||||
-rw-r--r-- | src/dal/dataprovider.h | 6 | ||||
-rw-r--r-- | src/dal/mysqldataprovider.cpp | 48 | ||||
-rw-r--r-- | src/dal/mysqldataprovider.h | 3 | ||||
-rw-r--r-- | src/dal/sqlitedataprovider.h | 16 |
5 files changed, 74 insertions, 14 deletions
diff --git a/src/dal/dataprovider.cpp b/src/dal/dataprovider.cpp index f6bcbdf..b0f05d3 100644 --- a/src/dal/dataprovider.cpp +++ b/src/dal/dataprovider.cpp @@ -27,21 +27,28 @@ namespace dal PerformTransaction::PerformTransaction(DataProvider *dataProvider) : mDataProvider(dataProvider) + , mTransactionStarted(false) , mCommitted(false) { - mDataProvider->beginTransaction(); + if (!mDataProvider->inTransaction()) { + mDataProvider->beginTransaction(); + mTransactionStarted = true; + } } PerformTransaction::~PerformTransaction() { - if (!mCommitted) + if (mTransactionStarted && !mCommitted) mDataProvider->rollbackTransaction(); } void PerformTransaction::commit() { - mDataProvider->commitTransaction(); - mCommitted = true; + if (mTransactionStarted) { + mDataProvider->commitTransaction(); + mCommitted = true; + mTransactionStarted = false; + } } diff --git a/src/dal/dataprovider.h b/src/dal/dataprovider.h index 1764ef1..83d1c8c 100644 --- a/src/dal/dataprovider.h +++ b/src/dal/dataprovider.h @@ -59,6 +59,7 @@ public: private: DataProvider *mDataProvider; + bool mTransactionStarted; bool mCommitted; }; @@ -156,6 +157,11 @@ class DataProvider throw (std::runtime_error) = 0; /** + * Returns whether the data provider is currently in a transaction. + */ + virtual bool inTransaction() const = 0; + + /** * Returns the number of changed rows by the last executed SQL * statement. * diff --git a/src/dal/mysqldataprovider.cpp b/src/dal/mysqldataprovider.cpp index 3e3d1c6..4e5f286 100644 --- a/src/dal/mysqldataprovider.cpp +++ b/src/dal/mysqldataprovider.cpp @@ -43,6 +43,7 @@ const std::string MySqlDataProvider::CFGPARAM_MYSQL_PWD_DEF = "mana"; MySqlDataProvider::MySqlDataProvider() throw() : mDb(0) + , mInTransaction(false) { } @@ -229,7 +230,21 @@ void MySqlDataProvider::beginTransaction() throw std::runtime_error(error); } - mysql_autocommit(mDb, AUTOCOMMIT_OFF); + if (inTransaction()) + { + const std::string error = "Trying to begin a transaction while anoter " + "one is still open!"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + + if (mysql_autocommit(mDb, AUTOCOMMIT_OFF)) { + const std::string error = "Error while trying to disable autocommit"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + + mInTransaction = true; execSql("BEGIN"); LOG_DEBUG("SQL: started transaction"); } @@ -245,12 +260,27 @@ void MySqlDataProvider::commitTransaction() throw std::runtime_error(error); } + if (!inTransaction()) + { + const std::string error = "Trying to commit a transaction while no " + "one is open!"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + if (mysql_commit(mDb) != 0) { LOG_ERROR("MySqlDataProvider::commitTransaction: " << mysql_error(mDb)); throw DbSqlQueryExecFailure(mysql_error(mDb)); } - mysql_autocommit(mDb, AUTOCOMMIT_ON); + + if (mysql_autocommit(mDb, AUTOCOMMIT_ON)) { + const std::string error = "Error while trying to enable autocommit"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + + mInTransaction = false; LOG_DEBUG("SQL: commited transaction"); } @@ -265,15 +295,29 @@ void MySqlDataProvider::rollbackTransaction() throw std::runtime_error(error); } + if (!inTransaction()) + { + const std::string error = "Trying to rollback a transaction while no " + "one is open!"; + LOG_ERROR(error); + throw std::runtime_error(error); + } + if (mysql_rollback(mDb) != 0) { LOG_ERROR("MySqlDataProvider::rollbackTransaction: " << mysql_error(mDb)); throw DbSqlQueryExecFailure(mysql_error(mDb)); } mysql_autocommit(mDb, AUTOCOMMIT_ON); + mInTransaction = false; LOG_DEBUG("SQL: transaction rolled back"); } +bool MySqlDataProvider::inTransaction() const +{ + return mInTransaction; +} + unsigned MySqlDataProvider::getModifiedRows() const { if (!mIsConnected) diff --git a/src/dal/mysqldataprovider.h b/src/dal/mysqldataprovider.h index c553032..528d4be 100644 --- a/src/dal/mysqldataprovider.h +++ b/src/dal/mysqldataprovider.h @@ -128,6 +128,8 @@ class MySqlDataProvider: public DataProvider void rollbackTransaction() throw (std::runtime_error); + bool inTransaction() const; + /** * Returns the number of changed rows by the last executed SQL * statement. @@ -197,6 +199,7 @@ class MySqlDataProvider: public DataProvider MYSQL *mDb; /**< the handle to the database connection */ MYSQL_STMT *mStmt; /**< the prepared statement to process */ std::vector<MYSQL_BIND*> mBind; + bool mInTransaction; }; diff --git a/src/dal/sqlitedataprovider.h b/src/dal/sqlitedataprovider.h index bbe4b87..40ef361 100644 --- a/src/dal/sqlitedataprovider.h +++ b/src/dal/sqlitedataprovider.h @@ -121,6 +121,14 @@ class SqLiteDataProvider: public DataProvider throw (std::runtime_error); /** + * Returns wheter the connection has a open transaction or is in auto- + * commit mode. + * + * @return true, if a transaction is open. + */ + bool inTransaction() const; + + /** * Returns the number of changed rows by the last executed SQL * statement. * @@ -169,14 +177,6 @@ class SqLiteDataProvider: public DataProvider /** defines the default value of the CFGPARAM_SQLITE_DB parameter */ static const std::string CFGPARAM_SQLITE_DB_DEF; - /** - * Returns wheter the connection has a open transaction or is in auto- - * commit mode. - * - * @return true, if a transaction is open. - */ - bool inTransaction() const; - sqlite3 *mDb; /**< the handle to the database connection */ sqlite3_stmt *mStmt; /**< the prepared statement to process */ }; |