In a PHP script working with a mysql database, I recently had the need to use a transaction at a point that happened to be inside another transaction. All my tests seem to
This page of the manual might interest you : 12.3.3. Statements That Cause an Implicit Commit; quoting a few sentences :
The statements listed in this section (and any synonyms for them) implicitly end a transaction, as if you had done a
COMMIT
before executing the statement.
And, a bit farther in the page :
Transaction-control and locking statements.
BEGIN
,LOCK TABLES
,SET autocommit = 1
(if the value is not already 1),START TRANSACTION
,UNLOCK TABLES
.
See also this paragraph :
Transactions cannot be nested.
This is a consequence of the implicitcommit
performed for any current transaction when you issue aSTART TRANSACTION
statement or one of its synonyms.
There are some great answers in this thread, however, if you use innoDB as your MySQL storage engine and are using MySQL 5.0.3 or higher, you get nested transactions right out of the box without the need for any extra work on your part or any of the fancy techniques described by others in this thread.
From the MySQL docs on XA Transactions:
MySQL 5.0.3 and up provides server-side support for XA transactions. Currently, this support is available for the InnoDB storage engine. The MySQL XA implementation is based on the X/Open CAE document Distributed Transaction Processing: The XA Specification. This document is published by The Open Group and available at http://www.opengroup.org/public/pubs/catalog/c193.htm. Limitations of the current XA implementation are described in Section E.5, “Restrictions on XA Transactions”.
My XA Transaction Example Just For You:
# Start a new XA transaction
XA START;
# update my bank account balance, they will never know!
UPDATE `bank_accounts` SET `balance` = 100000 WHERE `id` = 'mine';
# $100,000.00 is a bit low, I'm going to consider adding more, but I'm not sure so
# I will start a NESTED transaction and debate it...
XA START;
# max int money! woo hoo!
UPDATE `bank_accounts` SET `balance` = 2147483647 WHERE `id` = 'mine';
# maybe thats too conspicuous, better roll back
XA ROLLBACK;
# The $100,000 UPDATE still applies here, but the max int money does not, going for it!
XA COMMIT;
# Oh No! Sirens! It's the popo's!!! run!!
# What the hell are they using ints for money columns anyway! Ahhhh!
MySQL Documentation For XA Transactions:
I <3 XA Transactions 4 Eva!
You might want to check your testing methadology. Outside of MaxDB, MySQL doesn't support anything remotely like nested transactions.
I want to be sure - are transactions within transactions valid in mysql?
No.
MySql doesn't support nested transactions. There are a few ways that you can emulate it though. First, you can use savepoints as a form of transaction, so that gives you two levels of transactions; I've used this for testing, but I'm not sure about the limitations, if you use it in production code. A simpler solution is to ignore the second begin transaction
and instead increase a counter. For each commit
, you decrease it. Once you hit zero, you do an actual commit
. There are obvious limitations of this; Eg. a rollback will roll all transactions back, but for a case where you only use transactions for error-handling, that may be acceptable.
It does: http://dev.mysql.com/doc/refman/5.0/en/xa.html