XA事务与MySQL

XA事务与MySQL
XA事务就是两阶段提交的一种实现方式

XA规范主要定义了事务管理器TM,和资源管理器RM之间的接口

根据2PC的规范,将一次事务分割成两个阶段

  1. prepare阶段

TM向所有RM发送prepare指令,RM接受到指令后执行数据修改和日志记录等操作,然后返回 可以提交/不可提交 给TM

(按照我的理解应该类似于MySQL在开启一个事务之后,只差最后的COMMIT或者ROLLBACK的状态)

  1. commit阶段

TM接受到所有RM的prepare结果

如果有RM返回是 不可提交 或者超时,那么向所有RM发送ROLLBACK命令

如果所有RM都返回可以提交,那么向所有RM发送COMMIT命令

XA的异常情况处理

MySQL与XA事务的关系有两种情况

  1. 内部XA

在使用innodb作为存储引擎,并且开启binlog的情况下,MySQL同时维护了binlog日志与innodb的redo log

为了保证这两个日志的一致性,MySQL使用了XA事务,由于只在单机上工作,所以被称为内部XA

  1. 外部XA

就是一般谈论的分布式事务了

MySQL支持XA START/END/PREPARE/COMMIT这些sql语句,通过使用这些命令,我们是可以完成分布式事务的

状态转移图如下

在这里插入图片描述

(我有点不能理解的是,为什么一定需要XA END这个语句,直接XA PREPARE不行吗)

在MySQL5.7.7之前,XA事务是有bug的

如果有一个XA事务处于PREPARE状态

  1. 如果连接关闭,或者MySQL服务器正常退出,这个事务会被回滚(但是根据XA规范,这个事务应该被保留)

  2. 如果MySQL服务器被强制结束,在重启之后,用XA RECOVER命令可以看到这个事务,这个事务也可以被XA COMMIT所提交,但是相关的binlog记录会丢失,这样就会导致数据库引擎中的数据与binlog中的数据不一致 (参考资料)

这两个bug被提出了十年之久,终于在5.7.7中被修正了(第一个bug阿里自己也搞了个修正)

就目前来看,MySQL的XA事务现在做得还不错,应该是可用的

还是有一些不能理解的地方

  1. 官方文档中强调:在使用分布式事务的时候,需要使用串行隔离级别,为什么?

(As with nondistributed transactions, SERIALIZABLE may be preferred if your applications are sensitive to read phenomena. REPEATABLE READ may not be sufficient for distributed transactions.)

原因:为了尽可能提高分布式事物的隔离级别,如果分库上使用MySQL默认的RR,那么导致总的分布式事务的隔离级别为RU

参考资料:

  1. MySQL binlog 组提交与 XA(两阶段提交)

  2. MySQL redolog与组提交 资料1 资料2 资料3 资料4

  3. MySQL官方的XA文档

  4. XA事务的隔离级别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值