强一致性的分布式事务几种模式对比(php有了新方案)
四种分布式事务模式的对比(仅供参考)
特性 | mysql XA | LCN模式 | AT模式 | RT模式 |
---|---|---|---|---|
支持语言 | 无限制 | java | java | php |
使用难度 | 简单 | 困难 | 困难 | 简单 |
数据一致性 | 100% | 强 | 中 | 100% |
并发性能 | 中 | 低 | 中 | 高 |
业务入侵 | 无 | 无 | 低 | 无 |
sql修复入侵 | 无 | 无 | 低 | 无 |
分布式事务嵌套 | 不支持 | 支持 | 支持 | 支持 |
子服务嵌套事务 | 不支持 | 不支持 | 不支持 | 支持 |
sql事务嵌套 | 支持 | 不支持 | 不支持 | 支持 |
通信协议 | 不能跨服务 | dubbo | dubbo | http |
事务隔离级别 | 可重复读 | 未知 | 读未提交 | 读已提交 |
事务类型 | 长事务 | 长事务 | 短事务 | 短事务 |
死锁 | 多 | 多 | 少 | 少 |
orm框架 | 适用 | 绑定 | 绑定 | 适用 |
支持sql语句 | 所有 | 未知 | 不支持多表和批量操作 | 绝大部分 |
第一种 XA模式
MySQL XA 是基于Open Group的Distributed Transaction Processing标准实现的,支持分布式事务,允许多个数据库实例参与一个全局的事务。MySQl XA 从MySQL 5.0 开始引入,仅innodb存储引擎支持MySQL XA事务。
第二种 LCN模式
LCN 是一款事务协调性的框架,框架本身并不创建事务,只是对本地事务做协调控制。因此该框架与其他第三方的框架兼容性强,支持所有的关系型数据库事务,支持多数据源,支持与第三方数据库框架一块使用(例如 sharding-jdbc),在使用框架的时候只需要添加分布式事务的注解即可,对业务的侵入性低。
官网地址:www.codingapi.com/docs/home/
第三种 AT模式
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务,提供了 AT、TCC、SAGA 和 XA 四种事务模式。这里主要说明的是AT模式。Seata的AT模式本质上对2PC协议的优化演进,它是工作在Java应用层的中间件,通过对支持本地 ACID 事务的关系型数据库的分支事务的协调来驱动完成全局事务。
官网地址:seata.io/zh-cn/
第四种 RT模式
reset-transaction是一款开源的为php各大框架提供分布式事务的composer包。RT模式是reset transaction的简称,也就是重置型事务的意思。特别适用于orm框架,写法跟普通事务一致,默认支持mysql,http协议的服务,简单易用。
博客:Laravel基于RT模式实现分布式事务(突破技术支持子服务嵌套事务)
对RT模式的疑问
疑问1:RT模式相比AT模式,少了事务协调器(TC),但是为何很多方面都要优于AT模式?
AT模式请求每个api服务后,都提交了事务。如果其中某一个服务出现异常了,需要全部回滚,这时AT模式需要每次执行sql语句时,生成反向sql并且记录到undo_log表,事务协调器把异常服务和前面正常服务的所有反向sql执行一遍,这样子实现了所有数据回退。另外,批量操作的sql是没法生成反向sql。
相比之下,RT模式请求每个api服务后,都全部回滚,生成正向sql并且记录到reset_transaction表。所以不需要事务管理器去管理服务。如果其中某一个服务出现异常了,由业务发起rollback或者网络异常下放弃往后执行代码。奇怪,连代码执行一半放弃了都没事,那是因为所有的正向sql只有最后一步提交事务的时候,才全部处理。
总之一句话,AT模式需要降低指标去补救前面请求过的服务,相反,RT模式什么都不补救,躺平着。
疑问2:RT模式相比AT模式,是如何做到数据一致性100%?
AT模式在本地事务提交前必须先向服务端注册分支,分支注册信息中包含由表名和行主键组成的全局锁,简单来说就像mysql的串行化。通过串行化实现了数据的一致性。如果dba想要执行sql脚本修复数据,这时会有脏数据产生。
相比之下,RT模式在本地事务调用api服务接口都不加锁,但是要保留校验值。在最后一步提交时候,把跨服务转为跨数据库,转为mysql xa提交,并且对sql的校验值进行校验,以此来保证数据一致性100%,并且大大地提升性能。
提问3:RT模式为何喜欢跟AT模式比较,不跟TCC模式比较呢?
RT模式和AT模式是属于强一致性事务,TCC是属于最终一致性事务,所以RT模式最适合的比较对象是AT模式。而且AT模式是阿里seata框架的主要推广的模式,使用的人特别多,已经成为强一致性分布式事务的领头羊。在RT模式下,一个请求内,每个服务只调用一次的话,性能跟tcc差不多。
提问4:RT模式有哪些缺点呢?
RT模式因为是重置型,有一个缺点是每次的读档,是把之前相同一个服务下执行过的sql语句又重新执行一遍。如果调用订单服务次数是m,调用账户服务次数是n,总共执行sql语句的次数等于(1+m)m/2+(1+n)n/2。不过也不用太担心,因为读档是把mysql拼接成一条sql语句,加快读档的效率。这一块,后续还在研究中,努力做得更加完善。
个人笔记
由于分布式事务解决方案这一块,几乎被java垄断,所以我也只能硬着头皮去阅读seata的源码。正是不断地了解seata,越加发现RT模式的闪光点,所以忍不住要把RT模式的闪光点展示出来。希望php也能诞生出强一致性的分布式解决方案,方便php的微服务框架解决数据一致性的问题。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: