diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-08-24 13:42:04 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-08-24 13:42:04 +0200 |
commit | f5d79a0cd5dc12a430d17bbdca7ec5aacb45996c (patch) | |
tree | 10518f3819b50b78470d3612a36a14580ca1ad11 /odb | |
parent | 27e362857cf748a54c62b157113cd4abf7eff570 (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.
Diffstat (limited to 'odb')
-rw-r--r-- | odb/database.hxx | 4 | ||||
-rw-r--r-- | odb/database.ixx | 6 | ||||
-rw-r--r-- | odb/transaction.cxx | 41 | ||||
-rw-r--r-- | odb/transaction.hxx | 48 |
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_; }; } |