summaryrefslogtreecommitdiffstats
path: root/src/dal
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2010-10-30 10:54:27 +0200
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2010-10-30 12:51:31 +0200
commit6129e5bf1fe0128eb7742a7270e1264b65798bbb (patch)
treef54afc81e8dcc0d14a13721170f497f8e2df6d2b /src/dal
parente4713d0203311fdfcfef72ae5632782075159a56 (diff)
downloadmanaserv-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.cpp15
-rw-r--r--src/dal/dataprovider.h6
-rw-r--r--src/dal/mysqldataprovider.cpp48
-rw-r--r--src/dal/mysqldataprovider.h3
-rw-r--r--src/dal/sqlitedataprovider.h16
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 */
};