aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-08-24 13:42:04 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-08-24 13:42:04 +0200
commitf5d79a0cd5dc12a430d17bbdca7ec5aacb45996c (patch)
tree10518f3819b50b78470d3612a36a14580ca1ad11
parent27e362857cf748a54c62b157113cd4abf7eff570 (diff)
Add support for transaction multiplexing
Also delay getting a connection until after we do all the sanity checks (e.g., that there is no active transaction). Otherwise we are running risk of getting blocked rather than throwing an exception.
-rw-r--r--odb/database.hxx4
-rw-r--r--odb/database.ixx6
-rw-r--r--odb/transaction.cxx41
-rw-r--r--odb/transaction.hxx48
4 files changed, 71 insertions, 28 deletions
diff --git a/odb/database.hxx b/odb/database.hxx
index 2e6c79d..5ec98a7 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -177,8 +177,8 @@ namespace odb
// Transactions.
//
public:
- transaction_impl*
- begin ();
+ virtual transaction_impl*
+ begin () = 0;
// Connections.
//
diff --git a/odb/database.ixx b/odb/database.ixx
index ccbbe41..dbdcaec 100644
--- a/odb/database.ixx
+++ b/odb/database.ixx
@@ -12,12 +12,6 @@ namespace odb
{
}
- inline transaction_impl* database::
- begin ()
- {
- return connection ()->begin ();
- }
-
inline connection_ptr database::
connection ()
{
diff --git a/odb/transaction.cxx b/odb/transaction.cxx
index e1fed91..70abd0c 100644
--- a/odb/transaction.cxx
+++ b/odb/transaction.cxx
@@ -19,10 +19,16 @@ namespace odb
static ODB_TLS_POINTER (transaction) current_transaction;
transaction::
- transaction (transaction_impl* impl)
+ transaction (transaction_impl* impl, bool make_current)
: finalized_ (false), impl_ (impl)
{
- tls_set (current_transaction, this);
+ if (make_current && tls_get (current_transaction) != 0)
+ throw already_in_transaction ();
+
+ impl_->start ();
+
+ if (make_current)
+ tls_set (current_transaction, this);
}
transaction::
@@ -60,14 +66,32 @@ namespace odb
}
void transaction::
+ current (transaction& t)
+ {
+ tls_set (current_transaction, &t);
+ }
+
+ void transaction::
+ reset_current ()
+ {
+ transaction* t (0);
+ tls_set (current_transaction, t);
+ }
+
+ void transaction::
commit ()
{
if (finalized_)
throw transaction_already_finalized ();
finalized_ = true;
- transaction* t (0);
- tls_set (current_transaction, t);
+
+ if (tls_get (current_transaction) == this)
+ {
+ transaction* t (0);
+ tls_set (current_transaction, t);
+ }
+
impl_->commit ();
}
@@ -78,8 +102,13 @@ namespace odb
throw transaction_already_finalized ();
finalized_ = true;
- transaction* t (0);
- tls_set (current_transaction, t);
+
+ if (tls_get (current_transaction) == this)
+ {
+ transaction* t (0);
+ tls_set (current_transaction, t);
+ }
+
impl_->rollback ();
}
diff --git a/odb/transaction.hxx b/odb/transaction.hxx
index c2b1f77..0d4f518 100644
--- a/odb/transaction.hxx
+++ b/odb/transaction.hxx
@@ -22,8 +22,11 @@ namespace odb
typedef odb::database database_type;
typedef odb::connection connection_type;
+ // If the second argument is false, then this transaction is not
+ // made the current transaction of the thread.
+ //
explicit
- transaction (transaction_impl*);
+ transaction (transaction_impl*, bool make_current = true);
// Unless the transaction has already been finalized (explicitly
// committed or rolled back), the destructor will roll it back.
@@ -46,16 +49,26 @@ namespace odb
connection_type&
connection ();
+ // Return true if there is a transaction in effect.
+ //
+ static bool
+ has_current ();
+
// Return current transaction or throw if there is no transaction
// in effect.
//
static transaction&
current ();
- // Return true if there is a transaction in effect.
+ // Set the current thread's transaction.
//
- static bool
- has_current ();
+ static void
+ current (transaction&);
+
+ // Revert to the no transaction in effect state for the current thread.
+ //
+ static void
+ reset_current ();
public:
transaction_impl&
@@ -74,21 +87,17 @@ namespace odb
class LIBODB_EXPORT transaction_impl
{
- protected:
- friend class transaction;
-
+ public:
typedef odb::database database_type;
typedef odb::connection connection_type;
- transaction_impl (database_type& db, connection_type& c)
- : database_ (db), connection_ (c)
- {
- }
-
virtual
~transaction_impl ();
virtual void
+ start () = 0;
+
+ virtual void
commit () = 0;
virtual void
@@ -103,12 +112,23 @@ namespace odb
connection_type&
connection ()
{
- return connection_;
+ return *connection_;
+ }
+
+ protected:
+ transaction_impl (database_type& db)
+ : database_ (db), connection_ (0)
+ {
+ }
+
+ transaction_impl (database_type& db, connection_type& c)
+ : database_ (db), connection_ (&c)
+ {
}
protected:
database_type& database_;
- connection_type& connection_;
+ connection_type* connection_;
};
}