XA 事务通过以下状态进行:
用于
XA START
启动 XA 事务并将其放入ACTIVE
状态。对于
ACTIVE
XA 事务,发出组成事务的 SQL 语句,然后发出一条XA END
语句。XA END
将交易置于IDLE
状态。对于
IDLE
XA 事务,您可以发出XA PREPARE
语句或XA COMMIT ... ONE PHASE
语句:XA PREPARE
将交易置于PREPARED
状态。此时的XA RECOVER
语句在其输出中包含事务的xid
值,因为XA RECOVER
列出了处于该PREPARED
状态的所有 XA 事务。XA COMMIT ... ONE PHASE
准备并提交交易。该xid
值未列出,XA RECOVER
因为事务终止。
对于
PREPARED
XA 事务,您可以发出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 节“导致隐式提交的语句” 中列出了前面的注释适用的 语句。