MANAGING TRANSACTION PROCESSING
MySQL supports the use of several underlying database
engines. Not all engines support explicit management of
transaction processing, as will be explained in this tutorial.
The two most commonly used engines are MyISAM and InnoDB. The
former does not support explicit transaction management and the
latter does. This is why the sample tables used in this book
were created to use InnoDB instead of the more commonly used
MyISAM. If you need transaction processing functionality in
your applications, be sure to use the correct engine type.
Transaction processing is used to maintain database integrity
by ensuring that batches of MySQL operations execute completely
or not at all.
Understanding Transaction Processing
Note
Not All Engines Support Transactions As explained in
Tutorial 26, "Creating and Manipulating Tables," MySQL supports
the use of several underlying database engines. Not all engines
support explicit management of transaction processing, as will
be explained in this tutorial. The two most commonly used
engines are MyISAM and InnoDB. The former does not support
explicit transaction management and the latter does. This is
why the sample tables used in this book were created to use
InnoDB instead of the more commonly used MyISAM. If you need
transaction processing functionality in your applications, be
sure to use the correct engine type.
Transaction processing is used to maintain database
integrity by ensuring that batches of MySQL operations execute
completely or not at all.
As explained back in Tutorial 20, "Joining Tables,"
relational databases are designed so data is stored in multiple
tables to facilitate easier data manipulation, management, and
reuse. Without going in to the hows and whys of relational
database design, take it as a given that well-designed database
schemas are relational to some degree.
The orders tables you've been using in prior tutorials are a
good example of this. Orders are stored in two tables: orders
stores actual orders, and orderitems stores the individual
items ordered. These two tables are related to each other using
unique IDs called primary keys (as discussed in Tutorial 1,
"Understanding SQL"). These tables, in turn, are related to
other tables containing customer and product information.
The process of adding an order to the system is as
follows:
- Check if the customer is already in the database
(present in the customers table). If not, add him or
her.
- Retrieve the customer's ID.
- Add a row to the orders table associating it with the
customer ID.
- Retrieve the new order ID assigned in the orders
table.
- Add one row to the orderitems table for each item
ordered, associating it with the orders table by the
retrieved ID (and with the products table by product
ID).
Now imagine that some database failure (for example, out of
disk space, security restrictions, table locks) prevents this
entire sequence from completing. What would happen to your
data?
Well, if the failure occurred after the customer was added
and before the orders table was added, there is no real
problem. It is perfectly valid to have customers without
orders. When you run the sequence again, the inserted customer
record will be retrieved and used. You can effectively pick up
where you left off.
But what if the failure occurred after the orders row was
added, but before the orderitems rows were added? Now you'd
have an empty order sitting in your database.
Worse, what if the system failed during adding the
orderitems rows? Now you'd end up with a partial order in your
database, but you wouldn't know it.
How do you solve this problem? That's where transaction
processing comes in. Transaction processing is a mechanism used
to manage sets of MySQL operations that must be executed in
batches to ensure that databases never contain the results of
partial operations. With transaction processing, you can ensure
that sets of operations are not aborted mid-processingthey
either execute in their entirety or not at all (unless
explicitly instructed otherwise). If no error occurs, the
entire set of statements is committed (written) to the database
tables. If an error does occur, a rollback (undo) can occur to
restore the database to a known and safe state.
So, looking at the same example, this is how the process
would work:
- Check if the customer is already in the database; if
not, add him or her.
- Commit the customer information.
- Retrieve the customer's ID.
- Add a row to the orders table.
- If a failure occurs while adding the row to orders,
roll back.
- Retrieve the new order ID assigned in the orders
table.
- Add one row to the orderitems table for each item
ordered.
- If a failure occurs while adding rows to orderitems,
roll back all the orderitems rows added and the orders
row.
- Commit the order information.
When working with transactions and transaction processing,
there are a few keywords that'll keep reappearing. Here are the
terms you need to know:
- Transaction A block of SQL statements
- Rollback The process of undoing specified SQL
statements
- Commit Writing unsaved SQL statements to the database
tables
- Savepoint A temporary placeholder in a transaction set
to which you can issue a rollback (as opposed to rolling
back an entire transaction)
Controlling Transactions
Now that you know what transaction processing is, let's look
at what is involved in managing transactions.
The key to managing transactions involves breaking your SQL
statements into logical chunks and explicitly stating when data
should be rolled back and when it should not.
The MySQL statement used to mark the start of a transaction
is
• Input
START TRANSACTION
Using ROLLBACK
The MySQL ROLLBACK command is used to roll back (undo) MySQL
statements, as seen in this next statement:
• Input
SELECT * FROM ordertotals;
START TRANSACTION;
DELETE FROM ordertotals;
SELECT * FROM ordertotals;
ROLLBACK;
SELECT * FROM ordertotals;
• Analysis
This example starts by displaying the contents of the
ordertotals table (this table was populated in Tutorial 29,
"Using Cursors"). First a SELECT is performed to show that the
table is not empty. Then a transaction is started, and all of
the rows in ordertables are deleted with a DELETE statement.
Another SELECT verifies that, indeed, ordertotals is empty.
Then a ROLLBACK statement is used to roll back all statements
until the START TRANSACTION, and the final SELECT shows that
the table is no longer empty.
Obviously, ROLLBACK can only be used within a transaction
(after a START TRANSACTION command has been issued).
Tip
Which Statements Can You Roll
Back? Transaction processing is used to manage INSERT, UPDATE,
and DELETE statements. You cannot roll back SELECT statements.
(There would not be much point in doing so anyway.) You cannot
roll back CREATE or DROP operations. These statements may be
used in a transaction block, but if you perform a rollback they
will not be undone.
Using COMMIT
MySQL statements are usually executed and written directly
to the database tables. This is known as an implicit commit the
commit (write or save) operation happens automatically.
Within a transaction block, however, commits do not occur
implicitly. To force an explicit commit, the COMMIT statement
is used, as seen here:
• Input
START TRANSACTION;
DELETE FROM orderitems WHERE order_num = 20010;
DELETE FROM orders WHERE order_num = 20010;
COMMIT;

• Analysis
In this example, order number 20010 is deleted entirely from
the system. Because this involves updating two database tables,
orders and orderitems, a transaction block is used to ensure
that the order is not partially deleted. The final COMMIT
statement writes the change only if no error occurred. If the
first DELETE worked, but the second failed, the DELETE would
not be committed (it would effectively be automatically
undone).
Note
Implicit Transaction Closes After a COMMIT or ROLLBACK
statement has been executed, the transaction is automatically
closed (and future changes will implicitly
commit).
Using Savepoints
Simple ROLLBACK and COMMIT statements enable you to write or
undo an entire transaction. Although this works for simple
transactions, more complex transactions might require partial
commits or rollbacks.
For example, the process of adding an order described
previously is a single transaction. If an error occurs, you
only want to roll back to the point before the orders row was
added. You do not want to roll back the addition to the
customers table (if there was one).
To support the rollback of partial transactions, you must be
able to put placeholders at strategic locations in the
transaction block. Then, if a rollback is required, you can
roll back to one of the placeholders.
These placeholders are called save points, and to create one
use the SAVEPOINT statement, as follows:
• Input
SAVEPOINT delete1;
Each savepoint takes a unique name that identifies it so that,
when you roll back, MySQL knows where you are rolling back to.
To roll back to this save point, do the following:
• Input
ROLLBACK TO delete1;
Tip
The More Savepoints the Better
You can have as many save points as you'd like within your
MySQL code, and the more the better. Why? Because the more save
points you have the more flexibility you have in managing
rollbacks exactly as you need
them.
Note
Releasing Savepoints, Save points are automatically
released after a transaction completes (a ROLLBACK or COMMIT is
issued). As of MySQL 5, save points can also be explicitly
released using RELEASE SAVEPOINT.
Changing the Default Commit Behavior
As already explained, the default MySQL behavior is to
automatically commit any and all changes. In other words, any
time you execute a MySQL statement, that statement is actually
being performed against the tables, and the changes made occur
immediately. To instruct MySQL to not automatically commit
changes, you need to use the following statement:
• Input
SET autocommit=0;
• Analysis
The autocommit flag determines whether changes are committed
automatically without requiring a manual COMMIT statement.
Setting autocommit to 0 (false) instructs MySQL to not
automatically commit changes (until the flag is set back to
true).
Note
Flag Is Connection Specific The autocommit flag is per
connection, not server-wide.
Summary
In this tutorial, you learned that transactions are blocks
of SQL statements that must be executed as a batch. You learned
how to use the COMMIT and ROLLBACK statements to explicitly
manage when data is written and when it is undone. You also
learned how to use savepoints to provide a greater level of
control over rollback operations.
[Next]
|