MySQL supports local transactions (within a given client
      connection) through statements such as SET
      AUTOCOMMIT, START TRANSACTION,
      COMMIT, and ROLLBACK. See
      Section 13.4.1, “START TRANSACTION, COMMIT, and ROLLBACK Syntax”. Beginning with MySQL 5.0, XA transaction
      support is available, which enables MySQL to participate in
      distributed transactions as well. See Section 13.4.7, “XA Transactions”.
    
START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMMIT = {0 | 1}
        The START TRANSACTION and
        BEGIN statement begin a new transaction.
        COMMIT commits the current transaction,
        making its changes permanent. ROLLBACK rolls
        back the current transaction, canceling its changes. The
        SET AUTOCOMMIT statement disables or enables
        the default autocommit mode for the current connection.
      
        Beginning with MySQL 5.0.3, the optional WORK
        keyword is supported for COMMIT and
        RELEASE, as are the CHAIN
        and RELEASE clauses. CHAIN
        and RELEASE can be used for additional
        control over transaction completion. The value of the
        completion_type system variable determines
        the default completion behavior. See
        Section 5.2.2, “Server System Variables”.
      
        The AND CHAIN clause causes a new transaction
        to begin as soon as the current one ends, and the new
        transaction has the same isolation level as the just-terminated
        transaction. The RELEASE clause causes the
        server to disconnect the current client connection after
        terminating the current transaction. Including the
        NO keyword suppresses
        CHAIN or RELEASE
        completion, which can be useful if the
        completion_type system variable is set to
        cause chaining or release completion by default.
      
By default, MySQL runs with autocommit mode enabled. This means that as soon as you execute a statement that updates (modifies) a table, MySQL stores the update on disk.
        If you are using a transaction-safe storage engine (such as
        InnoDB, BDB, or
        NDB Cluster), you can disable autocommit mode
        with the following statement:
      
SET AUTOCOMMIT=0;
        After disabling autocommit mode by setting the
        AUTOCOMMIT variable to zero, you must use
        COMMIT to store your changes to disk or
        ROLLBACK if you want to ignore the changes
        you have made since the beginning of your transaction.
      
        To disable autocommit mode for a single series of statements,
        use the START TRANSACTION statement:
      
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summary=@A WHERE type=1; COMMIT;
        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 is the recommended way to start an
        ad-hoc transaction.
      
        The BEGIN statement differs from the use of
        the BEGIN keyword that starts a
        BEGIN ... END compound statement. The latter
        does not begin a transaction. See Section 17.2.5, “BEGIN ... END Compound Statement Syntax”.
      
You can also begin a transaction like this:
START TRANSACTION WITH CONSISTENT SNAPSHOT;
        The WITH CONSISTENT SNAPSHOT clause starts a
        consistent read for storage engines that are capable of it.
        Currently, this applies only to InnoDB. The
        effect is the same as issuing a START
        TRANSACTION followed by a SELECT
        from any InnoDB table. See
        Section 14.2.10.4, “Consistent Non-Locking Read”.
      
        The WITH CONSISTENT SNAPSHOT clause does not
        change the current transaction isolation level, so it provides a
        consistent snapshot only if the current isolation level is one
        that allows consistent read (REPEATABLE READ
        or SERIALIZABLE).
      
        Beginning a transaction causes an implicit UNLOCK
        TABLES to be performed.
      
For best results, transactions should be performed using only tables managed by a single transactional storage engine. Otherwise, the following problems can occur:
            If you use tables from more than one transaction-safe
            storage engine (such as InnoDB and
            BDB), and the transaction isolation level
            is not SERIALIZABLE, it is possible that
            when one transaction commits, another ongoing transaction
            that uses the same tables will see only some of the changes
            made by the first transaction. That is, the atomicity of
            transactions is not guaranteed with mixed engines and
            inconsistencies can result. (If mixed-engine transactions
            are infrequent, you can use SET TRANSACTION
            ISOLATION LEVEL to set the isolation level to
            SERIALIZABLE on a per-transaction basis
            as necessary.)
          
If you use non-transaction-safe tables within a transaction, any changes to those tables are stored at once, regardless of the status of autocommit mode.
            If you issue a ROLLBACK statement after
            updating a non-transactional table within a transaction, an
            ER_WARNING_NOT_COMPLETE_ROLLBACK warning
            occurs. Changes to transaction-safe tables are rolled back,
            but not changes to non-transaction-safe tables.
          
        Each transaction is stored in the binary log in one chunk, upon
        COMMIT. Transactions that are rolled back are
        not logged. (Exception:
        Modifications to non-transactional tables cannot be rolled back.
        If a transaction that is rolled back includes modifications to
        non-transactional tables, the entire transaction is logged with
        a ROLLBACK statement at the end to ensure
        that the modifications to those tables are replicated.) See
        Section 5.12.3, “The Binary Log”.
      
        You can change the isolation level for transactions with
        SET TRANSACTION ISOLATION LEVEL. See
        Section 13.4.6, “SET TRANSACTION Syntax”.
      
        Rolling back can be a slow operation that may occur without the
        user having explicitly asked for it (for example, when an error
        occurs). Because of this, SHOW PROCESSLIST
        displays Rolling back in the
        State column for the connection during
        implicit and explicit (ROLLBACK SQL
        statement) rollbacks.
      
Some statements cannot be rolled back. In general, these include data definition language (DDL) statements, such as those that create or drop databases, those that create, drop, or alter tables or stored routines.
        You should design your transactions not to include such
        statements. If you issue a statement early in a transaction that
        cannot be rolled back, and then another statement later fails,
        the full effect of the transaction cannot be rolled back in such
        cases by issuing a ROLLBACK statement.
      
        Each of the following statements (and any synonyms for them)
        implicitly end a transaction, as if you had done a
        COMMIT before executing the statement:
      
            ALTER FUNCTION, ALTER
            PROCEDURE, ALTER TABLE,
            BEGIN, CREATE
            DATABASE, CREATE FUNCTION,
            CREATE INDEX, CREATE
            PROCEDURE, CREATE TABLE,
            DROP DATABASE, DROP
            FUNCTION, DROP INDEX,
            DROP PROCEDURE, DROP
            TABLE, LOAD MASTER DATA,
            LOCK TABLES, LOAD DATA
            INFILE, RENAME TABLE,
            SET AUTOCOMMIT=1, START
            TRANSACTION, TRUNCATE TABLE,
            UNLOCK TABLES.
          
            UNLOCK TABLES commits a transaction only
            if any tables currently are locked.
          
            The CREATE TABLE, CREATE
            DATABASE DROP DATABASE, and
            TRUNCATE TABLE statements cause an
            implicit commit beginning with MySQL 5.0.8. The
            ALTER FUNCTION, ALTER
            PROCEDURE, CREATE FUNCTION,
            CREATE PROCEDURE, DROP
            FUNCTION, and DROP PROCEDURE
            statements cause an implicit commit beginning with MySQL
            5.0.13.
          
            The CREATE TABLE statement in
            InnoDB is processed as a single
            transaction. This means that a ROLLBACK
            from the user does not undo CREATE TABLE
            statements the user made during that transaction.
          
        Transactions cannot be nested. This is a consequence of the
        implicit COMMIT performed for any current
        transaction when you issue a START
        TRANSACTION statement or one of its synonyms.
      
SAVEPOINTidentifierROLLBACK [WORK] TO SAVEPOINTidentifierRELEASE SAVEPOINTidentifier
        InnoDB supports the SQL statements
        SAVEPOINT and ROLLBACK TO
        SAVEPOINT. Starting from MySQL 5.0.3, RELEASE
        SAVEPOINT and the optional WORK
        keyword for ROLLBACK are supported as well.
      
        The SAVEPOINT statement sets a named
        transaction savepoint with a name of
        identifier. If the current
        transaction has a savepoint with the same name, the old
        savepoint is deleted and a new one is set.
      
        The ROLLBACK TO SAVEPOINT statement rolls
        back a transaction to the named savepoint. Modifications that
        the current transaction made to rows after the savepoint was set
        are undone in the rollback, but InnoDB does
        not release the row locks that were stored
        in memory after the savepoint. (Note that for a new inserted
        row, the lock information is carried by the transaction ID
        stored in the row; the lock is not separately stored in memory.
        In this case, the row lock is released in the undo.) Savepoints
        that were set at a later time than the named savepoint are
        deleted.
      
        If the ROLLBACK TO SAVEPOINT statement
        returns the following error, it means that no savepoint with the
        specified name exists:
      
ERROR 1181: Got error 153 during ROLLBACK
        The RELEASE SAVEPOINT statement removes the
        named savepoint from the set of savepoints of the current
        transaction. No commit or rollback occurs. It is an error if the
        savepoint does not exist.
      
        All savepoints of the current transaction are deleted if you
        execute a COMMIT, or a
        ROLLBACK that does not name a savepoint.
      
Beginning with MySQL 5.0.17, a new savepoint level is created when a stored function is invoked or a trigger is activated. The savepoints on previous levels become unavailable and thus do not conflict with savepoints on the new level. When the function or trigger terminates, any savepoints it created are released and the previous savepoint level is restored.
LOCK TABLES
    tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
    [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ...
UNLOCK TABLES
        LOCK TABLES locks tables for the current
        thread. If any of the tables are locked by other threads, it
        blocks until all locks can be acquired. UNLOCK
        TABLES releases any locks held by the current thread.
        All tables that are locked by the current thread are implicitly
        unlocked when the thread issues another LOCK
        TABLES, or when the connection to the server is
        closed.
      
        A table lock protects only against inappropriate reads or writes
        by other clients. The client holding the lock, even a read lock,
        can perform table-level operations such as DROP
        TABLE.
      
        Note the following regarding the use of LOCK
        TABLES with transactional tables:
      
            LOCK TABLES is not transaction-safe and
            implicitly commits any active transactions before attempting
            to lock the tables. Also, beginning a transaction (for
            example, with START TRANSACTION)
            implicitly performs an UNLOCK TABLES.
            (See Section 13.4.3, “Statements That Cause an Implicit Commit”.)
          
            The correct way to use LOCK TABLES with
            transactional tables, such as InnoDB
            tables, is to set AUTOCOMMIT = 0 and not
            to call UNLOCK TABLES until you commit
            the transaction explicitly. When you call LOCK
            TABLES, InnoDB internally takes
            its own table lock, and MySQL takes its own table lock.
            InnoDB releases its table lock at the
            next commit, but for MySQL to release its table lock, you
            have to call UNLOCK TABLES. You should
            not have AUTOCOMMIT = 1, because then
            InnoDB releases its table lock
            immediately after the call of LOCK
            TABLES, and deadlocks can very easily happen. Note
            that we do not acquire the InnoDB table
            lock at all if AUTOCOMMIT=1, to help old
            applications avoid unnecessary deadlocks.
          
            ROLLBACK does not release MySQL's
            non-transactional table locks.
          
        To use LOCK TABLES, you must have the
        LOCK TABLES privilege and the
        SELECT privilege for the involved tables.
      
        The main reasons to use LOCK TABLES are to
        emulate transactions or to get more speed when updating tables.
        This is explained in more detail later.
      
        If a thread obtains a READ lock on a table,
        that thread (and all other threads) can only read from the
        table. If a thread obtains a WRITE lock on a
        table, only the thread holding the lock can write to the table.
        Other threads are blocked from reading or writing the table
        until the lock has been released.
      
        The difference between READ LOCAL and
        READ is that READ LOCAL
        allows non-conflicting INSERT statements
        (concurrent inserts) to execute while the lock is held. However,
        this cannot be used if you are going to manipulate the database
        files outside MySQL while you hold the lock. For
        InnoDB tables, READ LOCAL
        is the same as READ as of MySQL 5.0.13.
        (Before that, READ LOCAL essentially does
        nothing: It does not lock the table at all, so for
        InnoDB tables, the use of READ
        LOCAL is deprecated because a plain consistent-read
        SELECT does the same thing, and no locks are
        needed.)
      
        When you use LOCK TABLES, you must lock all
        tables that you are going to use in your queries. While the
        locks obtained with a LOCK TABLES statement
        are in effect, you cannot access any tables that were not locked
        by the statement. Also, you cannot use a locked table multiple
        times in a single query. Use aliases instead, in which case you
        must obtain a lock for each alias separately.
      
mysql>LOCK TABLE t WRITE, t AS t1 WRITE;mysql>INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES mysql>INSERT INTO t SELECT * FROM t AS t1;
If your queries refer to a table by means of an alias, you must lock the table using that same alias. It does not work to lock the table without specifying the alias:
mysql>LOCK TABLE t READ;mysql>SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES
Conversely, if you lock a table using an alias, you must refer to it in your queries using that alias:
mysql>LOCK TABLE t AS myalias READ;mysql>SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES mysql>SELECT * FROM t AS myalias;
        WRITE locks normally have higher priority
        than READ locks to ensure that updates are
        processed as soon as possible. This means that if one thread
        obtains a READ lock and then another thread
        requests a WRITE lock, subsequent
        READ lock requests wait until the
        WRITE thread has gotten the lock and released
        it. You can use LOW_PRIORITY WRITE locks to
        allow other threads to obtain READ locks
        while the thread is waiting for the WRITE
        lock. You should use LOW_PRIORITY WRITE locks
        only if you are sure that eventually there will be a time when
        no threads have a READ lock.
      
        LOCK TABLES works as follows:
      
Sort all tables to be locked in an internally defined order. From the user standpoint, this order is undefined.
If a table is locked with a read and a write lock, put the write lock before the read lock.
Lock one table at a time until the thread gets all locks.
        This policy ensures that table locking is deadlock free. There
        are, however, other things you need to be aware of about this
        policy: If you are using a LOW_PRIORITY WRITE
        lock for a table, it means only that MySQL waits for this
        particular lock until there are no threads that want a
        READ lock. When the thread has gotten the
        WRITE lock and is waiting to get the lock for
        the next table in the lock table list, all other threads wait
        for the WRITE lock to be released. If this
        becomes a serious problem with your application, you should
        consider converting some of your tables to transaction-safe
        tables.
      
        You can safely use KILL to terminate a thread
        that is waiting for a table lock. See Section 13.5.5.3, “KILL Syntax”.
      
        Note that you should not lock any tables
        that you are using with INSERT DELAYED
        because in that case the INSERT is performed
        by a separate thread.
      
        Normally, you do not need to lock tables, because all single
        UPDATE statements are atomic; no other thread
        can interfere with any other currently executing SQL statement.
        However, there are a few cases when locking tables may provide
        an advantage:
      
            If you are going to run many operations on a set of
            MyISAM tables, it is much faster to lock
            the tables you are going to use. Locking
            MyISAM tables speeds up inserting,
            updating, or deleting on them. The downside is that no
            thread can update a READ-locked table
            (including the one holding the lock) and no thread can
            access a WRITE-locked table other than
            the one holding the lock.
          
            The reason some MyISAM operations are
            faster under LOCK TABLES is that MySQL
            does not flush the key cache for the locked tables until
            UNLOCK TABLES is called. Normally, the
            key cache is flushed after each SQL statement.
          
            If you are using a storage engine in MySQL that does not
            support transactions, you must use LOCK
            TABLES if you want to ensure that no other thread
            comes between a SELECT and an
            UPDATE. The example shown here requires
            LOCK TABLES to execute safely:
          
LOCK TABLES trans READ, customer WRITE; SELECT SUM(value) FROM trans WHERE customer_id=some_id; UPDATE customer SET total_value=sum_from_previous_statementWHERE customer_id=some_id; UNLOCK TABLES;
            Without LOCK TABLES, it is possible that
            another thread might insert a new row in the
            trans table between execution of the
            SELECT and UPDATE
            statements.
          
        You can avoid using LOCK TABLES in many cases
        by using relative updates (UPDATE customer SET
        )
        or the value=value+new_valueLAST_INSERT_ID() function. See
        Section 1.9.5.3, “Transactions and Atomic Operations”.
      
        You can also avoid locking tables in some cases by using the
        user-level advisory lock functions GET_LOCK()
        and RELEASE_LOCK(). These locks are saved in
        a hash table in the server and implemented with
        pthread_mutex_lock() and
        pthread_mutex_unlock() for high speed. See
        Section 12.9.4, “Miscellaneous Functions”.
      
See Section 7.3.1, “Locking Methods”, for more information on locking policy.
        You can lock all tables in all databases with read locks with
        the FLUSH TABLES WITH READ LOCK statement.
        See Section 13.5.5.2, “FLUSH Syntax”. This is a very convenient way to
        get backups if you have a filesystem such as Veritas that can
        take snapshots in time.
      
        Note: If you use ALTER
        TABLE on a locked table, it may become unlocked. See
        Section A.7.1, “Problems with ALTER TABLE”.
      
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
This statement sets the transaction isolation level for the next transaction, globally, or for the current session.
        The default behavior of SET TRANSACTION is to
        set the isolation level for the next (not yet started)
        transaction. If you use the GLOBAL keyword,
        the statement sets the default transaction level globally for
        all new connections created from that point on. Existing
        connections are unaffected. You need the
        SUPER privilege to do this. Using the
        SESSION keyword sets the default transaction
        level for all future transactions performed on the current
        connection.
      
        For descriptions of each InnoDB transaction
        isolation level, see
        Section 14.2.10.3, “InnoDB and TRANSACTION ISOLATION LEVEL”.
        InnoDB supports each of these levels in MySQL
        5.0. The default level is REPEATABLE
        READ.
      
        To set the initial default global isolation level for
        mysqld, use the
        --transaction-isolation option. See
        Section 5.2.1, “mysqld Command Options”.
      
        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 I.5, “Restrictions on XA Transactions”.
      
        On the client side, there are no special requirements. The XA
        interface to a MySQL server consists of SQL statements that
        begin with the XA keyword. MySQL client
        programs must be able to send SQL statements and to understand
        the semantics of the XA statement interface. They do not need be
        linked against a recent client library. Older client libraries
        also will work.
      
Currently, among the MySQL Connectors, MySQL Connector/J 5.0.0 supports XA directly (by means of a class interface that handles the XA SQL statement interface for you).
XA supports distributed transactions; that is, the ability to allow multiple separate transactional resources to participate in a global transaction. Transactional resources often are RDBMSs but may be other kinds of resources.
        A global transaction involves several actions that are
        transactional in themselves, but that all must either complete
        successfully as a group, or all be rolled back as a group. In
        essence, this extends ACID properties “up a level”
        so that multiple ACID transactions can be executed in concert as
        components of a global operation that also has ACID properties.
        (However, for a distributed transaction, you must use the
        SERIALIZABLE isolation level to achieve ACID
        properties. It is enough to use REPEATABLE
        READ for a non-distributed transaction, but not for a
        distributed transaction.)
      
Some examples of distributed transactions:
An application may act as an integration tool that combines a messaging service with an RDBMS. The application makes sure that transactions dealing with message sending, retrieval, and processing that also involve a transactional database all happen in a global transaction. You can think of this as “transactional email.”
An application performs actions that involve different database servers, such as a MySQL server and an Oracle server (or multiple MySQL servers), where actions that involve multiple servers must happen as part of a global transaction, rather than as separate transactions local to each server.
A bank keeps account information in an RDBMS and distributes and receives money via automated teller machines (ATMs). It is necessary to ensure that ATM actions are correctly reflected in the accounts, but this cannot be done with the RDBMS alone. A global transaction manager integrates the ATM and database resources to ensure overall consistency of financial transactions.
Applications that use global transactions involve one or more Resource Managers and a Transaction Manager:
A Resource Manager (RM) provides access to transactional resources. A database server is one kind of resource manager. It must be possible to either commit or roll back transactions managed by the RM.
A Transaction Manager (TM) coordinates the transactions that are part of a global transaction. It communicates with the RMs that handle each of these transactions. The individual transactions within a global transaction are “branches” of the global transaction. Global transactions and their branches are identified by a naming scheme described later.
The MySQL implementation of XA MySQL enables a MySQL server to act as a Resource Manager that handles XA transactions within a global transaction. A client program that connects to the MySQL server acts as the Transaction Manager.
To carry out a global transaction, it is necessary to know which components are involved, and bring each component to a point when it can be committed or rolled back. Depending on what each component reports about its ability to succeed, they must all commit or roll back as an atomic group. That is, either all components must commit, or all components musts roll back. To manage a global transaction, it is necessary to take into account that any component or the connecting network might fail.
The process for executing a global transaction uses two-phase commit (2PC). This takes place after the actions performed by the branches of the global transaction have been executed.
In the first phase, all branches are prepared. That is, they are told by the TM to get ready to commit. Typically, this means each RM that manages a branch records the actions for the branch in stable storage. The branches indicate whether they are able to do this, and these results are used for the second phase.
In the second phase, the TM tells the RMs whether to commit or roll back. If all branches indicated when they were prepared that they will be able to commit, all branches are told to commit. If any branch indicated when it was prepared that it will not be able to commit, all branches are told to roll back.
In some cases, a global transaction might use one-phase commit (1PC). For example, when a Transaction Manager finds that a global transaction consists of only one transactional resource (that is, a single branch), that resource can be told to prepare and commit at the same time.
To perform XA transactions in MySQL, use the following statements:
XA {START|BEGIN} xid [JOIN|RESUME]
XA END xid [SUSPEND [FOR MIGRATE]]
XA PREPARE xid
XA COMMIT xid [ONE PHASE]
XA ROLLBACK xid
XA RECOVER
          For XA START, the JOIN
          and RESUME clauses are not supported.
        
          For XA END the SUSPEND [FOR
          MIGRATE] clause is not supported.
        
          Each XA statement begins with the XA
          keyword, and most of them require an
          xid value. An
          xid is an XA transaction
          identifier. It indicates which transaction the statement
          applies to. xid values are supplied
          by the client, or generated by the MySQL server. An
          xid value has from one to three
          parts:
        
xid:gtrid[,bqual[,formatID]]
          gtrid is a global transaction
          identifier, bqual is a branch
          qualifier, and formatID is a number
          that identifies the format used by the
          gtrid and
          bqual values. As indicated by the
          syntax, bqual and
          formatID are optional. The default
          bqual value is
          '' if not given. The default
          formatID value is 1 if not given.
        
          gtrid and
          bqual must be string literals, each
          up to 64 bytes (not characters) long.
          gtrid and
          bqual can be specified in several
          ways. You can use a quoted string ('ab'),
          hex string (0x6162,
          X'ab'), or bit value
          (b').
        nnnn'
          formatID is an unsigned integer.
        
          The gtrid and
          bqual values are interpreted in
          bytes by the MySQL server's underlying XA support routines.
          However, while an SQL statement containing an XA statement is
          being parsed, the server works with some specific character
          set. To be safe, write gtrid and
          bqual as hex strings.
        
          xid values typically are generated
          by the Transaction Manager. Values generated by one TM must be
          different from values generated by other TMs. A given TM must
          be able to recognize its own xid
          values in a list of values returned by the XA
          RECOVER statement.
        
          XA START 
          starts an XA transaction with the given
          xidxid value. Each XA transaction must
          have a unique xid value, so the
          value must not currently be used by another XA transaction.
          Uniqueness is assessed using the
          gtrid and
          bqual values. All following XA
          statements for the XA transaction must be specified using the
          same xid value as that given in the
          XA START statement. If you use any of those
          statements but specify an xid value
          that does not correspond to some existing XA transaction, an
          error occurs.
        
          One or more XA transactions can be part of the same global
          transaction. All XA transactions within a given global
          transaction must use the same gtrid
          value in the xid value. For this
          reason, gtrid values must be
          globally unique so that there is no ambiguity about which
          global transaction a given XA transaction is part of. The
          bqual part of the
          xid value must be different for
          each XA transaction within a global transaction. (The
          requirement that bqual values be
          different is a limitation of the current MySQL XA
          implementation. It is not part of the XA specification.)
        
          The XA RECOVER statement returns
          information for those XA transactions on the MySQL server that
          are in the PREPARED state. (See
          Section 13.4.7.2, “XA Transaction States”.) The output includes a row for
          each such XA transaction on the server, regardless of which
          client started it.
        
          XA RECOVER output rows look like this (for
          an example xid value consisting of
          the parts 'abc', 'def',
          and 7):
        
mysql> XA RECOVER;
+----------+--------------+--------------+--------+
| formatID | gtrid_length | bqual_length | data   |
+----------+--------------+--------------+--------+
|        7 |            3 |            3 | abcdef |
+----------+--------------+--------------+--------+
The output columns have the following meanings:
              formatID is the
              formatID part of the
              transaction xid
            
              gtrid_length is the length in bytes of
              the gtrid part of the
              xid
            
              bqual_length is the length in bytes of
              the bqual part of the
              xid
            
              data is the concatenation of the
              gtrid and
              bqual parts of the
              xid
            
An XA transaction progresses through the following states:
              Use XA START to start an XA transaction
              and put it in the ACTIVE state.
            
              For an ACTIVE XA transaction, issue the
              SQL statements that make up the transaction, and then
              issue an XA END statement. XA
              END puts the transaction in the
              IDLE state.
            
              For an IDLE XA transaction, you can
              issue either an XA PREPARE statement or
              an XA COMMIT ... ONE PHASE statement:
            
                  XA PREPARE puts the transaction in
                  the PREPARED state. An XA
                  RECOVER statement at this point will include
                  the transaction's xid value
                  in its output, because XA RECOVER
                  lists all XA transactions that are in the
                  PREPARED state.
                
                  XA COMMIT ... ONE PHASE prepares
                  and commits the transaction. The
                  xid value will not be
                  listed by XA RECOVER because the
                  transaction terminates.
                
              For a PREPARED XA transaction, you can
              issue an XA COMMIT statement to commit
              and terminate the transaction, or XA
              ROLLBACK to roll back and terminate the
              transaction.
            
Here is a simple XA transaction that inserts a row into a table as part of a global transaction:
mysql>XA START 'xatest';Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO mytable (i) VALUES(10);Query OK, 1 row affected (0.04 sec) mysql>XA END 'xatest';Query OK, 0 rows affected (0.00 sec) mysql>XA PREPARE 'xatest';Query OK, 0 rows affected (0.00 sec) mysql>XA COMMIT 'xatest';Query OK, 0 rows affected (0.00 sec)
          Within the context of a given client connection, XA
          transactions and local (non-XA) transactions are mutually
          exclusive. For example, if XA START has
          been issued to begin an XA transaction, a local transaction
          cannot be started until the XA transaction has been committed
          or rolled back. Conversely, if a local transaction has been
          started with START TRANSACTION, no XA
          statements can be used until the transaction has been
          committed or rolled back.