文章目录
1 xa协议
1.1 什么是xa协议?
XA协议采用两阶段提交方式来管理分布式事务。该协议分为预备和提交两个阶段:
- 预备:负责执行业务逻辑
- 提交:负责事务的commit
DTP模型
DTP (distributed Transaction Processing) 模型,是一个名叫 The Open Group 的组织提出的分布式事务处理规范,已经成为事实上的事务模型组件的行为标准。
DTP规范包括AP(应用程序)、RM(资源管理器)、TM(事务管理器)三部分组成,其具体分工如下:
- AP: 负责事务发起和结束;
- RM:负责管理每个数据库的连接数据源;
- TM:负责事务的全局管理,包括事务的生命周期管理和资源的分配协调;
XA协议
xa协议规范了TM和RM之间的的通信接口,在tm与多个rm之间形成了一个双向通信桥梁,保证操作多个数据库时的ACID特性!
1.2 二阶段提交-2pc
二阶段提交流程:
XA规范实现的分布式事务属于二阶段提交事务,通过两个阶段来完成分布式事务的提交:
- 第一阶段: 应用程序发起事务提交请求,事务管理器向各个资源管理器发起预提交请求;此时资源管理开始执行本地数据库事务,但是执行完成后不立刻提交事务,仅返回就绪或者未就绪状态;
- 第二阶段:
- 如果所有资源管理器返回就绪状态,事务管理器则会向各个资源管理器发送commit通知,资源管理器完成本地事务提交;
- 如果任意资源返回未就绪状态,事务管理器想所有资源发送事务回滚通知,此时各个资源管理回滚本地数据库事务,释放资源,返回结果通知;
二阶段提交问题:
- 阻塞问题:预提交阶段需要等到所有资源管理器返回状态,才能进入第二阶段;
- 数据不一致问题:如果网络阻塞,发生commit收不到通知,则存在数据不一致问题;
1.3 三阶段提交-3pc
三阶段提交流程:
三阶段提交未减少
二阶段提交的阻塞以及数据不一致问题而生,将执行过程分成了三个阶段来完成分布式事务提交:
- 第一阶段:准备阶段canCommit。事务管理器向各个资源管理器询问节点会否可以执行事务,都返回ok才进入第二阶段。
- 第二阶段:预提交阶段preCommit。各个节点真正执行事务阶段。
- 第三阶段:提交确认阶段doCommit。提交或者回滚阶段。
三阶段优缺点评估:
- 优点:
- TM和RM都引入超时机制,解决了长时间阻塞的问题;
- 检查阶段规避风险,避免失效问题;
- 缺点:
- 仍然未解决网络拥塞在提交阶段造成的数据不一致问题;
1.4 xa最佳实践
同一个事务上下文中需要协调多种资源(即数据库以及消息主题或队列时)才有必要使用X/Open XA接口
2 tcc协议
2.1 tcc方案简介
TCC方案是采用最终一致性的方式实现的服务层柔性分布式事务方案。
tcc协议采用try、confirm、cancel三个阶段来处理分布式事务。其中:
- try: 负责冻结提前预留资源;
- confirm:用来执行业务逻辑;
- cancel:用来释放业务资源;
如果在提交解决及确认和cancel阶段失败,tcc会不停充实调用confirm或者cancel方法,直到成功为止;
2.2 tcc方案评估
- 优点:
jta方案只能解决同一服务的多数据源的分布式事务问题
,tcc方案可以解决微服务架构内同一事务多个服务上连接数据库的数据提交操作。
- xa协议采用刚性事务方案,性能和吞吐率较低,tcc采用柔性分布式事务方案;
- 缺点:
- 对业务的侵入性较大:需要考虑预留资源、编写大量业务代码的try、confirm、cancel方法,考虑方法幂等性问题;
3 阿里seata方案
seata是阿里开源的一套的分布式事务解决方案,采用业务无侵入架构,解决分布式事务问题。
其具体结构如下指示:
下图是笔者整理的seata方案的事务提交流程:
下图为git仓库方案示意图:
seata相对于其它分布式事务的最大区别是在第一提交阶段就将各个事务进行了commit操作,这样节约了两个阶段持有锁的事件,提高了整体的执行效率。
通过xid管理全局事务,如果要全局回滚,通过xid找到对应的回滚日志记录,通过回滚记录生成反向更新sql
,进行更新回滚操作;
4 本文小结
本文主要讨论了分布式事务处理的一些基本方法,并对阿里开源的分布式事务处理框架作了一个简单的说明,后续会给出一篇关于其的详细分析文章。
对于分布式事务处理,主要分两种情况讨论:
同服务多数据源操作不同数据库的场景
:通常采用基于xa协议的二阶段提交方式,但是考虑到阻塞、数据库不一致问题,通常采用三阶段提交进行优化。多服务多数据源场景(微服务场景)
:通常采用tcc方案实现分布式事务,常用的中间件有tcc-transaction. tcc也是基于二阶段提交理论完成,但是将相关理论提到了服务层实现,属于一种侵入式方案。阿里seata方案设计初衷就是解决分布式事务低效、侵入问题,具有较好设计思路,但是稳定性有待验证。
本文参考
- 极客时间 - java性能调优-刘超
- https://github.com/seata/seata
- 《深入分布式缓存》