XA事务与MySQL

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

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

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

1. prepare阶段

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

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

2. 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

2. 外部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事务的隔离级别

posted @   qeDVuHG  阅读(5731)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示