0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 04:47:18 +08:00

Merge pull request #171 from volka/isolation_level

Add an option to set a transaction isolation level in start_transaction
This commit is contained in:
Roland Bock 2017-06-03 11:40:51 +02:00 committed by GitHub
commit 801428d4cf
4 changed files with 50 additions and 2 deletions

View File

@ -29,6 +29,7 @@
#include <string> #include <string>
#include <sqlpp11/connection.h> #include <sqlpp11/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/database/char_result.h> // You may use char result or bind result or both #include <sqlpp11/database/char_result.h> // You may use char result or bind result or both
#include <sqlpp11/database/bind_result.h> // to represent results of select and prepared select #include <sqlpp11/database/bind_result.h> // to represent results of select and prepared select
@ -130,7 +131,7 @@ namespace sqlpp
} }
//! start transaction //! start transaction
void start_transaction(); void start_transaction(isolation_level isolation = isolation_level::undefined);
//! commit transaction (or throw transaction if the transaction has been finished already) //! commit transaction (or throw transaction if the transaction has been finished already)
void commit_transaction(); void commit_transaction();

View File

@ -28,12 +28,21 @@
#define SQLPP_TRANSACTION_H #define SQLPP_TRANSACTION_H
#include <stdexcept> #include <stdexcept>
#include <ciso646>
namespace sqlpp namespace sqlpp
{ {
static constexpr bool quiet_auto_rollback = false; static constexpr bool quiet_auto_rollback = false;
static constexpr bool report_auto_rollback = true; static constexpr bool report_auto_rollback = true;
enum class isolation_level {
undefined, // use the current database default
serializable, // highest level, stronguest guarantee
repeatable_read, // DBMS holds read and write locks
read_committed, // DMBS holds read locks, non-repeatable reads can occur
read_uncommitted // lowest isolation level, dirty reads may occur
};
template <typename Db> template <typename Db>
class transaction_t class transaction_t
{ {
@ -48,6 +57,12 @@ namespace sqlpp
_db.start_transaction(); _db.start_transaction();
} }
transaction_t(Db& db, bool report_unfinished_transaction, isolation_level isolation)
: _db(db), _report_unfinished_transaction(report_unfinished_transaction)
{
_db.start_transaction(isolation);
}
transaction_t(const transaction_t&) = delete; transaction_t(const transaction_t&) = delete;
transaction_t(transaction_t&&) = default; transaction_t(transaction_t&&) = default;
transaction_t& operator=(const transaction_t&) = delete; transaction_t& operator=(const transaction_t&) = delete;
@ -90,6 +105,12 @@ namespace sqlpp
{ {
return {db, report_unfinished_transaction}; return {db, report_unfinished_transaction};
} }
template <typename Db>
transaction_t<Db> start_transaction(Db& db, isolation_level isolation, bool report_unfinished_transaction = report_auto_rollback)
{
return {db, report_unfinished_transaction, isolation};
}
} }
#endif #endif

View File

@ -28,12 +28,18 @@
#include <iostream> #include <iostream>
#include <sqlpp11/connection.h> #include <sqlpp11/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/data_types/no_value.h> #include <sqlpp11/data_types/no_value.h>
#include <sqlpp11/schema.h> #include <sqlpp11/schema.h>
#include <sqlpp11/serialize.h> #include <sqlpp11/serialize.h>
#include <sqlpp11/serializer_context.h> #include <sqlpp11/serializer_context.h>
#include <sstream> #include <sstream>
// an object to store internal Mock flags and values to validate in tests
struct InternalMockData {
sqlpp::isolation_level _last_isolation_level;
};
template <bool enforceNullResultTreatment> template <bool enforceNullResultTreatment>
struct MockDbT : public sqlpp::connection struct MockDbT : public sqlpp::connection
{ {
@ -244,6 +250,23 @@ struct MockDbT : public sqlpp::connection
{ {
return {name}; return {name};
} }
void start_transaction(sqlpp::isolation_level level)
{
// store temporarily to verify the expected level was used in testcases
_mock_data._last_isolation_level = level;
}
void rollback_transaction(bool)
{}
void commit_transaction()
{}
void report_rollback_failure(std::string)
{}
InternalMockData _mock_data;
}; };
using MockDb = MockDbT<false>; using MockDb = MockDbT<false>;

View File

@ -207,5 +207,8 @@ int Select(int, char* [])
for_each_field(row, to_cerr{}); for_each_field(row, to_cerr{});
} }
auto transaction = start_transaction(db, sqlpp::isolation_level::read_committed);
std::cout << (db._mock_data._last_isolation_level == sqlpp::isolation_level::read_committed) << std::endl;
return 0; return 0;
} }