Author: mysqlpp
Date: Thu Apr 30 04:23:52 2009
New Revision: 2511

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=2511&view=rev
Log:
Added a feature to Transaction, where it can send a SET TRANSACTION
ISOLATION LEVEL query before it starts the transaction proper, affecting
the isolation level and the scope of that change.  In response to a
mailing list request by Steven Davis.

Modified:
    trunk/examples/transaction.cpp
    trunk/lib/transaction.cpp
    trunk/lib/transaction.h

Modified: trunk/examples/transaction.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/transaction.cpp?rev=2511&r1=2510&r2=2511&view=diff
==============================================================================
--- trunk/examples/transaction.cpp (original)
+++ trunk/examples/transaction.cpp Thu Apr 30 04:23:52 2009
@@ -1,6 +1,6 @@
 /***********************************************************************
- transaction.cpp - Example showing how to use the transaction support in
-       MySQL++ v2.1 and up.
+ transaction.cpp - Example showing how to use MySQL++'s transaction
+       features.
 
  Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
  (c) 2004-2009 by Educational Technology Resources, Inc.  Others may
@@ -55,7 +55,15 @@
 
                // Insert a few rows in a single transaction set
                {
-                       mysqlpp::Transaction trans(con);
+                       // Use a higher level of transaction isolation than 
MySQL
+                       // offers by default.  This trades some speed for more
+                       // predictable behavior.  We've set it to affect all
+                       // transactions started through this DB server 
connection,
+                       // so it affects the next block, too, even if we don't
+                       // commit this one.
+                       mysqlpp::Transaction trans(con,
+                                       mysqlpp::Transaction::serializable,
+                                       mysqlpp::Transaction::session);
 
                        stock row("Sauerkraut", 42, 1.2, 0.75,
                                        mysqlpp::sql_date("2006-03-06"), 
mysqlpp::null);
@@ -74,6 +82,8 @@
                        
                // Now let's test auto-rollback
                {
+                       // Start a new transaction, keeping the same isolation 
level
+                       // we set above, since it was set to affect the session.
                        mysqlpp::Transaction trans(con);
                        cout << "\nNow adding catsup to the database..." << 
endl;
 

Modified: trunk/lib/transaction.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/transaction.cpp?rev=2511&r1=2510&r2=2511&view=diff
==============================================================================
--- trunk/lib/transaction.cpp (original)
+++ trunk/lib/transaction.cpp Thu Apr 30 04:23:52 2009
@@ -35,7 +35,7 @@
 using namespace mysqlpp;
 
 
-//// ctor //////////////////////////////////////////////////////////////
+//// ctors /////////////////////////////////////////////////////////////
 
 Transaction::Transaction(Connection& conn, bool consistent) :
 conn_(conn),
@@ -43,6 +43,37 @@
 {
        // Begin the transaction set
        Query q(conn_.query("START TRANSACTION"));
+       if (consistent) {
+               q << " WITH CONSISTENT SNAPSHOT";
+       }
+       q.execute();
+
+       // Setup succeeded, so mark our transaction as not-finished.
+       finished_ = false;
+}
+
+Transaction::Transaction(Connection& conn, IsolationLevel level,
+               IsolationScope scope, bool consistent) :
+conn_(conn),
+finished_(true)                // don't bother rolling it back if ctor fails
+{
+       // Set the transaction isolation level and scope as the user wishes
+       Query q(conn_.query("SET "));
+       if (scope == session) q << "SESSION ";
+       if (scope == global)  q << "GLOBAL ";
+       q << "TRANSACTION ISOLATION LEVEL ";
+       switch (level) {
+               case read_uncommitted:  q << "READ UNCOMMITTED";
+               case read_committed:    q << "READ COMMITTED";
+               case repeatable_read:   q << "REPEATABLE READ";
+               case serializable:              q << "SERIALIZABLE";
+       }
+       q.execute();
+
+       // Begin the transaction set.  Note that the above isn't part of
+       // the transaction, on purpose, so that scope == transaction affects
+       // *this* transaction, not the next one.
+       q << "START TRANSACTION";
        if (consistent) {
                q << " WITH CONSISTENT SNAPSHOT";
        }

Modified: trunk/lib/transaction.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/transaction.h?rev=2511&r1=2510&r2=2511&view=diff
==============================================================================
--- trunk/lib/transaction.h (original)
+++ trunk/lib/transaction.h Thu Apr 30 04:23:52 2009
@@ -46,13 +46,50 @@
 class MYSQLPP_EXPORT Transaction
 {
 public:
-       /// \brief Constructor
+       /// \brief Transaction isolation levels defined in SQL
+       ///
+       /// These values can be passed to one of the Transaction
+       /// constructors to change the way the database engine protects
+       /// transactions from other DB updates.  These values are in order
+       /// of increasing isolation, but decreasing performance.
+       enum IsolationLevel {
+               read_uncommitted,       ///< allow "dirty reads" from other 
transactions
+               read_committed,         ///< only read rows committed by other 
transactions
+               repeatable_read,        ///< other transactions do not affect 
repeated reads in this transaction
+               serializable            ///< this transaction prevents writes 
to any rows it accesses while it runs
+       };
+
+       /// \brief Isolation level scopes defined in SQL
+       ///
+       /// These values are only used with one of the Transaction
+       /// constructors, to select which transaction(s) our change to
+       // the isolation scope will affect.
+       enum IsolationScope {
+               this_transaction,       ///< change level for this transaction 
only
+               session,                        ///< change level for all 
transactions in this session
+               global                          ///< change level for all 
transactions on the DB server
+       };
+
+       /// \brief Simple constructor
        ///
        /// \param conn The connection we use to manage the transaction set
        /// \param consistent Whether to use "consistent snapshots" during
        /// the transaction. See the documentation for "START TRANSACTION"
        /// in the MySQL manual for more on this.
        Transaction(Connection& conn, bool consistent = false);
+
+       /// \brief Constructor allowing custom transaction isolation level
+       /// and scope
+       ///
+       /// \param conn The connection we use to manage the transaction set
+       /// \param level Isolation level to use for this transaction
+       /// \param scope Selects the scope of the isolation level change
+       /// \param consistent Whether to use "consistent snapshots" during
+       /// the transaction. See the documentation for "START TRANSACTION"
+       /// in the MySQL manual for more on this.
+       Transaction(Connection& conn, IsolationLevel level,
+                       IsolationScope scope = this_transaction,
+                       bool consistent = false);
 
        /// \brief Destructor
        ///


_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits

Reply via email to