数据库分布式事务 - XA
1. 理论
mysql5.0.3以上支持分布式事务
分布式事务涉及N个资源管理器和一个事务管理器
资源管理器:
事务管理器TM:与每个资源管理器通信
mysql执行XA时,mysql服务器相当于一个资源管理器,与mysql连接的客户端相当于事务管理器 - 没懂,我以为是相反的。
2. 语法:
-- 开启XA事务 XA START 'test','db1' -- 第一个提交阶段, 使事务进入prepare状态 XA END 'test','db1' XA PREPARE 'test','db1' -- 第二个提交阶段, 提交或者回滚分支事务 XA COMMIT 'test','db1' 或者(XA ROLLBACK 'test','db1') -- 查看当前处于prepare状态的分支事务的详细信息 XA RECOVER
'test','db1'解释:
'test','db1'是 xid, 每个XA事务必须有一个唯一的xid值,xid是一个xa事务标识符,用来唯一标识一个分布式事务。
xid格式: gtrid, bqual,formatId
相同的分布式事务使用相同的gtrid, 这样就可以明确知道XA事务属于哪个分布式事务
bqual是分支限定符,对于一个分布式事务中的每个分支事务,bqual值必须是唯一的
3.试验
准备2个数据库两个事务:
db1对应表TEST_XA_1
db2对应表TEST_XA_2
3.1 打开XA分布式事务
事务1
事务2:
事务1插入数据:
事务2插入数据:
3.2 一阶段提交
事务1 一阶段提交
事务2 一阶段提交
查看当前事务分支有两个
这时候还没提交,再开一个事务还是查不到数据- 查test_xa_2同样查不到数据
3.3 二阶段提交
事务1和事务2分别二阶段提交
3.4验证结果
再查结果提交了 - test_xa_2也有数据了
4 存在的问题
5.5以前的版本,如果数据库达到prepare状态时,数据库异常重新启动,服务器重新启动后,可以对分支事务提交或者回滚, 但是该事务不会写入binlog. 如果存在从库,会出现数据库主从不一致。
5.7解决了这个问题,但是还存在一些问题。如果需要使用分布式事务,尽量采用5.7或者更高版本。