From 7392db256c1587ff8fe87d95c5ae5c10f854f79e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 24 Aug 2011 13:42:04 +0200 Subject: 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. --- odb/sqlite/connection.cxx | 9 --------- odb/sqlite/database.cxx | 18 ++++++++++++++++++ odb/sqlite/database.hxx | 2 +- odb/sqlite/database.ixx | 18 ------------------ odb/sqlite/transaction-impl.cxx | 35 ++++++++++++++++++++++++++++------- odb/sqlite/transaction-impl.hxx | 10 ++++++---- odb/sqlite/transaction.hxx | 5 +++++ odb/sqlite/transaction.ixx | 6 ++++++ 8 files changed, 64 insertions(+), 39 deletions(-) (limited to 'odb/sqlite') diff --git a/odb/sqlite/connection.cxx b/odb/sqlite/connection.cxx index ffb70a7..1e9ff6f 100644 --- a/odb/sqlite/connection.cxx +++ b/odb/sqlite/connection.cxx @@ -82,9 +82,6 @@ namespace odb transaction_impl* connection:: begin () { - if (transaction::has_current ()) - throw already_in_transaction (); - return new transaction_impl ( connection_ptr (inc_ref (this)), transaction_impl::deferred); } @@ -92,9 +89,6 @@ namespace odb transaction_impl* connection:: begin_immediate () { - if (transaction::has_current ()) - throw already_in_transaction (); - return new transaction_impl ( connection_ptr (inc_ref (this)), transaction_impl::immediate); } @@ -102,9 +96,6 @@ namespace odb transaction_impl* connection:: begin_exclusive () { - if (transaction::has_current ()) - throw already_in_transaction (); - return new transaction_impl ( connection_ptr (inc_ref (this)), transaction_impl::exclusive); } diff --git a/odb/sqlite/database.cxx b/odb/sqlite/database.cxx index 6ce4621..04f788b 100644 --- a/odb/sqlite/database.cxx +++ b/odb/sqlite/database.cxx @@ -83,6 +83,24 @@ namespace odb details::options::print_usage (os); } + transaction_impl* database:: + begin () + { + return new transaction_impl (*this, transaction_impl::deferred); + } + + transaction_impl* database:: + begin_immediate () + { + return new transaction_impl (*this, transaction_impl::immediate); + } + + transaction_impl* database:: + begin_exclusive () + { + return new transaction_impl (*this, transaction_impl::exclusive); + } + odb::connection* database:: connection_ () { diff --git a/odb/sqlite/database.hxx b/odb/sqlite/database.hxx index 13c44e6..348f236 100644 --- a/odb/sqlite/database.hxx +++ b/odb/sqlite/database.hxx @@ -87,7 +87,7 @@ namespace odb // Transactions. // public: - transaction_impl* + virtual transaction_impl* begin (); transaction_impl* diff --git a/odb/sqlite/database.ixx b/odb/sqlite/database.ixx index f78d659..e7ae208 100644 --- a/odb/sqlite/database.ixx +++ b/odb/sqlite/database.ixx @@ -16,23 +16,5 @@ namespace odb return connection_ptr ( static_cast (connection_ ())); } - - inline transaction_impl* database:: - begin () - { - return connection ()->begin (); - } - - inline transaction_impl* database:: - begin_immediate () - { - return connection ()->begin_immediate (); - } - - inline transaction_impl* database:: - begin_exclusive () - { - return connection ()->begin_exclusive (); - } } } diff --git a/odb/sqlite/transaction-impl.cxx b/odb/sqlite/transaction-impl.cxx index 772b274..b425ed8 100644 --- a/odb/sqlite/transaction-impl.cxx +++ b/odb/sqlite/transaction-impl.cxx @@ -14,12 +14,38 @@ namespace odb namespace sqlite { transaction_impl:: + transaction_impl (database_type& db, lock l) + : odb::transaction_impl (db), lock_ (l) + { + } + + transaction_impl:: transaction_impl (connection_ptr c, lock l) - : odb::transaction_impl (c->database (), *c), connection_ (c) + : odb::transaction_impl (c->database (), *c), + connection_ (c), + lock_ (l) + { + } + + transaction_impl:: + ~transaction_impl () + { + } + + void transaction_impl:: + start () { + // Grab a connection if we don't already have one. + // + if (connection_ == 0) + { + connection_ = static_cast (database_).connection (); + odb::transaction_impl::connection_ = connection_.get (); + } + statement_cache& sc (connection_->statement_cache ()); - switch (l) + switch (lock_) { case deferred: { @@ -39,11 +65,6 @@ namespace odb } } - transaction_impl:: - ~transaction_impl () - { - } - void transaction_impl:: commit () { diff --git a/odb/sqlite/transaction-impl.hxx b/odb/sqlite/transaction-impl.hxx index 8b5687b..f0df824 100644 --- a/odb/sqlite/transaction-impl.hxx +++ b/odb/sqlite/transaction-impl.hxx @@ -21,10 +21,7 @@ namespace odb { class LIBODB_SQLITE_EXPORT transaction_impl: public odb::transaction_impl { - protected: - friend class connection; - friend class transaction; - + public: typedef sqlite::database database_type; typedef sqlite::connection connection_type; @@ -35,12 +32,16 @@ namespace odb exclusive }; + transaction_impl (database_type&, lock); transaction_impl (connection_ptr, lock); virtual ~transaction_impl (); virtual void + start (); + + virtual void commit (); virtual void @@ -51,6 +52,7 @@ namespace odb private: connection_ptr connection_; + lock lock_; }; } } diff --git a/odb/sqlite/transaction.hxx b/odb/sqlite/transaction.hxx index aecf8aa..b30a818 100644 --- a/odb/sqlite/transaction.hxx +++ b/odb/sqlite/transaction.hxx @@ -45,6 +45,11 @@ namespace odb static transaction& current (); + // Set the current thread's transaction. + // + static void + current (transaction&); + public: transaction_impl& implementation (); diff --git a/odb/sqlite/transaction.ixx b/odb/sqlite/transaction.ixx index f2c9cc8..e8a6594 100644 --- a/odb/sqlite/transaction.ixx +++ b/odb/sqlite/transaction.ixx @@ -37,5 +37,11 @@ namespace odb { return implementation ().connection (); } + + inline void transaction:: + current (transaction& t) + { + odb::transaction::current (t); + } } } -- cgit v1.1