分布式事务解法
[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/Distributed/How-To-Use-Distributed-Transaction.html
可搭配参考我的GitHub: 分布式事务.xmind
参见分布式事务有哪些
1. 基于XA协议的全局事务 (强一致性)
使用情况:一个工程对多个数据源(数据库需要支持XA协议)
基本功能:数据库时间功能+开源组件(知名的分布式事务管理器主要有atomikos、bitronix、narayana。其中,仅atomikos支持XA和TCC两种机制,bitronix、narayana仅支持XA机制。)
原理:2PC/3PC
单服务多数据库使用全局事务缺点:XA协议比较简单,成本较低,但是其单点问题,以及不能支持高并发(由于同步阻塞)依然是其最大的弱点(主要),2PC本身的缺陷也是一方面原因(次要)。
2PC & 3PC
2PC是两阶段提交协议(Two-Phase Commit)
它保证了所有参与节点在一个事务中要么全部提交,要么全部回滚。2PC有很高的可靠性和一致性,但需要进行两次网络通信和等待,从而导致性能上的一定损失。2PC适用于对事务强一致性要求高的系统,例如银行转账等
3PC是三阶段提交协议(Three-Phase Commit)
它在2PC的基础上增加了一个阶段,以减少等待时间和网络开销。3PC需要的网络通信比2PC更少,因此在性能方面略优于2PC。3PC适用于对事务一致性要求高,但是对性能有一定要求的系统,例如电子商务、在线游戏等
2PC & 3PC区别
2PC(canCommit、doCommit):
只有协调者有超时机制,超时后,发送回滚指令
3PC(canCommit、preCommit、doCommit):协调者和参与者都有超时机制
- 协调者触发超时:向所有参与者发送中断指令
- 参与者触发超时:当前为pre阶段进行中断,当前为do阶段进行提交
2PC & 3PC使用场景
2PC协议是最基本的分布式事务协议,包含了准备阶段和提交阶段。相较于3PC协议,2PC协议的实现较为简单,且在正常情况下的事务处理效率较高。然而,2PC协议存在阻塞问题,即当协调者失效时,参与者会一直阻塞等待,从而影响整个系统的性能
3PC协议在2PC协议的基础上增加了一个回滚阶段,可以更好地解决2PC协议存在的阻塞问题,同时也能够避免由于一方的失败导致整个事务的失败。然而,3PC协议的实现较为复杂,且在异常情况下的处理效率相对较低
因此,对于对可靠性要求较高的系统,可以选择3PC协议
;对于对效率要求较高的系统,可以选择2PC协议
2. TCC(强一致性)
使用情况:多系统 多数据源
原理:编程式事务,每个业务都要开发try,confirm,cancel 3个方法实现
- try->调用所有服务,把所有资源设置为中间状态(如订单设置为支付中,库存设置为冻结)
- confirm->把所有资源状态设置为完成(支付完成)
- cancel-> 把所有资源状态回滚回try前
缺点:程序复杂度高,confirm、cancel方法需要实现幂等
3. 基于可靠消息服务的分布式事务–MQ消息队列(最终一致性)
使用情况: 多系统 多数据源
原理:利用本地事务及MQ的事务消息(其实也不一定要用),确保本地事务未完成、消息发送出去;理想地认为对方一定能正确、成功消费消息;
缺点:
- 数据有一小段时间不一致
- 对方系统出现问题,不能正常消费信息,导致数据长期不一致
4. (最大努力通知)基于[不可靠]消息服务的分布式事务–MQ消息队列(最终一致性)
使用情况: 多系统 多数据源
原理:通过MQ延迟队列等实现的延迟通知服务, 通知服务会每隔1,5,10,30分钟重复通知 , 到达最大通知次数后, 需要人工通知或重置重试次数
优势(比基于可靠消息服务的分布式事务)
- 允许消费方短期异常(通过1,5,10,30分钟的间隔重试)
缺点:
- 数据有一小段时间不一致
- 对方系统出现问题,不能正常消费信息,导致数据长期不一致
- 编码比基于可靠消息服务的分布式事务复杂一些,需要实现延迟队列、自产自销+Http请求等实现重复通知
分布式事务选型
分布式事务选型主要要看场景,我们以流量充值
作为例子
- 流量充值涉及到订单支付
金钱交易严格用tcc
- 订单支付完后要给用户增加积分
这种情况这个必要成功(毕竟是内部系统),用最终消息一致性方案就行了;
- 订单支付完后还要给用户发送一条短信
短信一般是跟电信运营商的第三方接口对接,有可能成功有可能失败,用最大努力通知方案(每隔1,5,10,30分钟重复通知 直到达到最大重试次数)