Documentation Home

13.3.8.2 XA 事务状态

XA 事务通过以下状态进行:

  1. 用于XA START启动 XA 事务并将其放入 ACTIVE状态。

  2. 对于ACTIVEXA 事务,发出组成事务的 SQL 语句,然后发出一条XA END语句。 XA END将交易置于 IDLE状态。

  3. 对于IDLEXA 事务,您可以发出XA PREPARE语句或XA COMMIT ... ONE PHASE语句:

    • XA PREPARE将交易置于 PREPARED状态。此时的 XA RECOVER语句在其输出中包含事务的xid值,因为 XA RECOVER列出了处于该PREPARED状态的所有 XA 事务。

    • XA COMMIT ... ONE PHASE准备并提交交易。该 xid值未列出, XA RECOVER因为事务终止。

  4. 对于PREPAREDXA 事务,您可以发出XA COMMIT语句来提交和终止事务,或者 XA ROLLBACK回滚和终止事务。

下面是一个简单的 XA 事务,它将一行作为全局事务的一部分插入表中:

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)

在 MySQL 8.0.28 及更早版本中,在给定客户端连接的上下文中,XA 事务和本地(非 XA)事务是互斥的。例如,如果 XA START已发出以开始 XA 事务,则在提交或回滚 XA 事务之前无法启动本地事务。相反,如果本地事务已启动 START TRANSACTION,则在提交或回滚事务之前不能使用 XA 语句。

MySQL 8.0.29 及更高版本支持分离的 XA 事务,由 xa_detach_on_prepare系统变量启用(ON默认情况下)。分离的事务在执行后与当前会话断开连接XA PREPARE(并且可以由另一个连接提交或回滚)。这意味着当前会话可以自由启动新的本地事务或 XA 事务,而不必等待准备好的 XA 事务被提交或回滚。

当 XA 事务被分离时,连接对其准备的任何 XA 事务没有特殊了解。如果当前会话在另一个连接已经完成之后尝试提交或回滚给定的 XA 事务(即使是它准备的事务),则该尝试将被拒绝并返回无效的 XID 错误 ( ER_XAER_NOTA),因为请求xid不再存在。

笔记

分离的 XA 事务不能使用临时表。

当分离的 XA 事务被禁用(xa_detach_on_prepare设置为 OFF)时,XA 事务将保持连接状态,直到它被原始连接提交或回滚,如之前针对 MySQL 8.0.28 和更早版本所述。对于组复制中使用的 MySQL 服务器实例,不建议禁用分离的 XA 事务;有关详细信息,请参阅 服务器实例配置

如果 XA 事务处于该ACTIVE状态,则您不能发出任何导致隐式提交的语句。这将违反 XA 合同,因为您无法回滚 XA 事务。尝试执行这样的语句会引发以下错误:

ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed
when global transaction is in the ACTIVE state

第 13.3.3 节“导致隐式提交的语句” 中列出了前面的注释适用的 语句。