MySQL recently introduced transactions along with SQL for executing statements in a transactional context. By default, MySQL is in a state called autocommit. Autocommit mode means that any SQL you send to MySQL is executed immediately. In some cases, however, you may want to execute two or more SQL statements together as a single unit of work.
A transfer between two bank accounts is the perfect example of such a transaction. The banking system needs to make sure that the debit from the first account and the credit to the second account occur as a single unit of work. If they are treated separately, the server could in theory crash between the debit and the credit. The result would be that you would lose that money!
By making sure the two statements occur as a single unit of work, transactions ensure that the first statement can be “rolled back” in the event that the second statement fails. To use transactions in MySQL, you first need to create a table using a transactional table type such as BDB or InnoDB.[6]
If your MySQL install was not compiled with support for these table types, you cannot use transactions unless you reinstall. The SQL to create a transactional table specifies one of the transactional types:
CREATE TABLE ACCOUNT ( ACCOUNT_ID BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, BALANCE DOUBLE) TYPE = BDB;
For a transaction against a transactional table to work, you need to turn off autocommit. You can do this with the command:
SET AUTOCOMMIT=0;
Now you are ready to begin using MySQL transactions. Transactions
start with the BEGIN
command:
BEGIN;
Your mysql client is now in a transactional context with respect to the server. Any change you make to a transactional table will not be made permanent until you commit it. Changes to nontransactional tables, however, will take place immediately. In the case of the account transfer, we issue the following statements:
UPDATE ACCOUNT SET BALANCE = 50.25 WHERE ACCOUNT_ID = 1; UPDATE ACCOUNT SET BALANCE = 100.25 WHERE ACCOUNT_ID = 2;
Once you’re done with any changes, complete the
transaction by using the
COMMIT
command:
COMMIT;
The true advantage of transactions, of course, comes into play should
an error occur in executing the second statement. To abort the entire
transaction before a commit, issue the
ROLLBACK
command:
ROLLBACK;
In reality, the logic behind such complex transactional operations, including commits and rollbacks, requires solid design and well-structured error handling. We will cover these programmatic elements of transaction management in Chapter 8.
Of course, it would be useful if MySQL performed the actual math. It
can do just that as long as you store the values you want with a
SELECT
call:
SELECT @FIRST := BALANCE FROM ACCOUNT WHERE ACCOUNT_ID = 1; SELECT @SECOND := BALANCE FROM ACCOUNT WHERE ACCOUNT_ID = 2; UPDATE ACCOUNT SET BALANCE = @FIRST - 25.00 WHERE ACCOUNT_ID = 1; UPDATE ACCOUNT SET BALANCE = @SECOND + 25.00 WHERE ACCOUNT_ID = 2;
In addition to the COMMIT
command, a handful of
other commands will automatically end any current transaction as if a
COMMIT
had been issued. These commands are:
Chapter 8 covers some of the more intricate details of using transactions in database applications.