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事务的隔离级别
最新文章
- Log4j源代码学习
- 2.4G/5G频段WLAN各国使用信道表
- 百度的echart环形图颜色动态设置
- [学习笔记]tarjan求割边
- VS2013编译经常卡在正在从以下位置加载xxx.dll的符号
- windows phone 8.0 app 移植到windows10 app 页面类
- CCF真题之模板生成系统
- Dapper.NET使用(转)
- logback.xml_appender配置
- linux系统的crond服务
- 添加iis的wolf、wolf2、json支持
- 转载:c++ sort用法
- Java多线程——线程的生命周期和状态控制
- Vim中常用的命令行
- jsoup从表单中取数据
- 线性插值法的原理和python代码实现
- unmappable character for US-ASCII
- 用logstash,elasticSearch,kibana实现数据收集和统计分析工作
- 浅触selinux(持续更新)
- C#程序集系列03,引用多个module