블로그 이미지
지누구루

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2011. 12. 6. 11:36 공부

원본 :http://dev.mysql.com/tech-resources/articles/mysql-connector-cpp.html#trx

Using Transactions

A database transaction is a set of one or more statements that are executed together as a unit, so either all of the statements are executed, or none of them are executed. MySQL supports local transactions within a given client session through statements such as SET autocommit, START TRANSACTION, COMMIT, and ROLLBACK.

Disable AutoCommit Mode

By default, all the new database connections are in autocommit mode. In the autocommit mode, all the SQL statements will be executed and committed as individual transactions. The commit occurs when the statement completes or the next execute occurs, whichever comes first. In case of statements that return a ResultSet object, the statement completes when the last row of the ResultSet object has been retrieved or the ResultSet object has been closed.

One way to allow multiple statements to be grouped into a transaction is to disable autocommit mode. In other words, to use transactions, the Connection object must not be in autocommit mode. The Connection class provides the setAutoCommit method to enable or disable the autocommit. An argument of 0 to setAutoCommit() disables the autocommit, and a value of 1 enables the autocommit.

Connection *con;
..
/* disable the autocommit */
con -> setAutoCommit(0);

It is suggested to disable autocommit only while you want to be in transaction mode. This way, you avoid holding database locks for multiple statements, which increases the likelihood of conflicts with other users.

Commit or Rollback a Transaction

Once autocommit is disabled, changes to transaction-safe tables such as those for InnoDB and NDBCLUSTER are not made permanent immediately. You must explicitly call the method commit to make the changes permanent in the database or the method rollback to undo the changes. All the SQL statements executed after the previous call to commit() are included in the current transaction and committed together or rolled back as a unit.

The following code fragment, in which con is an active connection, illustrates a transaction.

Connection *con;
PreparedStatement *prep_stmt;

..
con -> setAutoCommit(0);

prep_stmt = con -> prepareStatement ("INSERT INTO City (CityName) VALUES (?)");

prep_stmt -> setString (1, "London, UK");
prep_stmt -> executeUpdate();

con -> rollback();

prep_stmt -> setString (1, "Paris, France");
prep_stmt -> executeUpdate();

con -> commit();

In this example, autocommit mode is disabled for the connection con, which means that the prepared statement prep_stmt is committed only when the method commit is called against this active connection object. In this case, an attempt has been made to insert two rows into the database using the prepared statement, but the first row with data "London, UK" was discarded by calling the rollback method while the second row with data "Paris, France" was inserted into the City table by calling the commit method.

Another example to show the alternate syntax to disable the autocommit, then to commit and/or rollback transactions explicitly.

Connection *con;
Statement *stmt;

..
stmt = con -> createStatement();

//stmt -> execute ("BEGIN;");
//stmt -> execute ("BEGIN WORK;");
stmt -> execute ("START TRANSACTION;");

stmt -> executeUpdate ("INSERT INTO City (CityName) VALUES ('London, UK')");
stmt -> execute ("ROLLBACK;");

stmt -> executeUpdate ("INSERT INTO City (CityName) VALUES ('Paris, France')");
stmt -> execute ("COMMIT;");

The START TRANSACTION or BEGIN statement starts a new transaction. COMMIT commits the current transaction to the database by making the changes permanent. ROLLBACK rolls back the current transaction by canceling the changes to the database. With START TRANSACTION, autocommit remains disabled until you end the transaction with COMMIT or ROLLBACK. The autocommit mode then reverts to its previous state.

BEGIN and BEGIN WORK are supported as aliases of START TRANSACTION for initiating a transaction. START TRANSACTION is standard SQL syntax and it is the recommended way to start an ad-hoc transaction.

Rollback to a Savepoint within a Transaction

The MySQL connector for C++ supports setting savepoints with the help of Savepoint class, which offer finer control within transactions. The Savepoint class allows you to partition a transaction into logical breakpoints, providing control over how much of the transaction gets rolled back.

As of this writing, InnoDB and Falcon storage engines support the savepoint transactions in MySQL 6.0.

To use transaction savepoints, the Connection object must not be in autocommit mode. When the autocommit is disabled, applications can set a savepoint within a transaction and then roll back all the work done after the savepoint. Note that enabling autocommit invalidates all the existing savepoints, and the Connector/C++ driver throws an InvalidArgumentException when an attempt has been made to roll back the outstanding transaction until the last savepoint.

A savepoint is either named or unnamed. You can specify a name to the savepoint by supplying a string to the Savepoint::setSavepoint method. If you do not specify a name, the savepoint is assigned an integer ID. You can retrieve the savepoint name using Savepoint::getSavepointName().

Signatures of some of the relevant methods are shown below. For the complete list of methods supported by Connection, Statement, PreparedStatement and Savepoint interfaces, check the connection.h, statement.h and prepared_statement.h headers in your Connector/C++ installation.

/* connection.h */
Savepoint* Connection::setSavepoint(const std::string& name);
void Connection::releaseSavepoint(Savepoint * savepoint);
void Connection::rollback(Savepoint * savepoint);

The following code fragment inserts a row into the table City, creates a savepoint SAVEPT1, then inserts a second row. When the transaction is later rolled back to SAVEPT1, the second insertion is undone, but the first insertion remains intact. In other words, when the transaction is committed, only the row containing "London, UK" will be added to the table City.

Connection *con;
PreparedStatement *prep_stmt;
Savepoint *savept;

..
prep_stmt = con -> prepareStatement ("INSERT INTO City (CityName) VALUES (?)");

prep_stmt -> setString (1, "London, UK");
prep_stmt -> executeUpdate();

savept = con -> setSavepoint ("SAVEPT1");

prep_stmt -> setString (1, "Paris, France");
prep_stmt -> executeUpdate();

con -> rollback (savept);
con -> releaseSavepoint (savept);

con -> commit();

The method Connection::releaseSavepoint takes a Savepoint object as a parameter and removes it from the current transaction. Any savepoints that have been created in a transaction are automatically released and become invalid when the transaction is committed, or when the entire transaction is rolled back. Rolling back a transaction to a savepoint automatically releases and invalids any other savepoints that were created after the savepoint in question. Once a savepoint has been released, any attempt to reference it in a rollback operation causes the SQLException to be thrown.

posted by 지누구루