微服务架构下,保证事务需求越来越多,针对分布式事务,有不同的方案
1.基于XA协议的两阶段提交方案
---这种方案,并发量大时,容易出现资源死锁,系统性能和处理吞吐量降低
XA 是指由 X/Open 组织提出的分布式事务处理的规范。XA规范主要定义了Transaction Manager(TM)和Resource Manager(RM)之间的接口,结构如下图所示。
XA协议的流程可大致分为三个步骤:
- 步骤1:APP向TM创建全局事务,TM向APP返回全局事务号。
- 步骤2:APP使用全局事务号,访问RM的资源(当RM为数据库时,资源访问就是SQL操作)。当RM第一次收到访问时,使用该全局事务号向TM注册,TM返回事务分支事务号。
- 步骤3:APP向TM发出全局事务提交请求,TM与参与事务的RM通信,进行提交处理,全部完成后,向APP返回结果。
2、基于消息队列
---完全依赖消息中间件,如果中间件挂掉,则整个系统出现崩溃,风险较高。
---另外两个事务之间用消息还好处理,如果多个事务之间进行传递,那么事务的回滚处理会麻烦很多,需要每个操作事务的日志以及分支事务的回滚做到精确
3、tcc模式(Try、Confirm、Cancel)
---这种模式对系统侵入大,需要大量的开发
TCC全局事务必须基于RM本地事务来实现
TCC事务框架应该接管Spring容器的TransactionManager
TCC事务框架应该具备故障恢复机制
TCC事务框架应该提供Confirm/Cancel服务的幂等性保障
TCC事务框架不能盲目的依赖Cancel业务来回滚事务
-
已生效的Try操作应该被其Cancel操作所回撤;
-
尚未生效的Try操作,则不应该执行其Cancel操作。这一点,不是幂等性所能解决的问题。如上文所述,幂等性是指服务被执行一次和被执行n(n>0)次所产生的影响相同。但是,未被执行和被执行过,二者效果肯定是不一样的,这不属于幂等性的范畴。
Cancel业务与Try业务并行,甚至先于Try操作完成
这个模式有开源的框架ByteTCC,地址:https://github.com/liuyangming/ByteTCC
ByteTCC基于Try/Confirm/Cancel机制实现,可与Spring容器无缝集成,兼容Spring的声明式事务管理。提供对dubbo框架、Spring Cloud的开箱即用的支持,可满足多数据源、跨应用、跨服务器等各种分布式事务场景的需求。
0.5版本的要求
4、阿里收费系统GTS
---配置灵活方便,但是收费
官方地址:https://www.aliyun.com/aliware/txc?spm=5176.8142029.388261.386.a72376f4lqvQxv
现在阿里的GTS开源了Seata系统:http://seata.io/zh-cn/docs/dev/mode/tcc-mode.html
5、业务系统控制,俗称业务系统自愈
我们系统的部分下单逻辑功能,feign调用优惠券、账号系统,调用成功赋值到temp,如果处理中异常了,则根据temp中不同的对象进行释放资源。前提是优惠券、账号都是加锁,扣减,释放加锁,也即TCC的逻辑思维,这样代码处理灵活。这样做法如果获取到异常,进行释放锁feign调用失败,释放资源也会出现失败,这样就需要人工加入处理。可以加上日志记录流水,这样系统自愈性更强。
6.阿里的GTS封装后开源的SeaTa开源软件支持分布式事务
SeaTa 支持XA跟TCC的两种模式,
Seata的实现原理,Seata有3个基本组成部分:
事务协调器(TC):维护全局事务和分支事务的状态,驱动全局提交或回滚。
事务管理器TM:定义全局事务的范围:开始全局事务,提交或回滚全局事务。
资源管理器(RM):管理分支事务正在处理的资源,与TC进行对话以注册分支事务并报告分支事务的状态,并驱动分支事务的提交或回滚。
Seata简单介绍
https://github.com/seata/seata
https://seata.io/zh-cn/index.html
https://github.com/seata/seata/releases/
官方文档:https://developer.aliyun.com/article/762045?spm=a2c6h.12873639.0.0.6cd63285hGCET1
https://seata.io/zh-cn/index.html?spm=a2c6h.12873639.0.0.fce52d29oQEFsy
具体demo以及实践待处理;
seata的具体实践的几个帖子:
https://blog.csdn.net/lifetragedy/article/details/104060200
https://blog.csdn.net/hosaos/article/details/89136666
总结:
可靠消息与TCC模式通过避免XA两阶段提交对数据资源的长期锁定提升了性能,通过在数据库外部实现事务机制达到了最终一致性,但牺牲了应用灵活性,需要开发人员实现事务检查与回滚的细节,面临着花费大量精力保证应用正确性的问题。
GTS目标是在性能开销可接受的情况下,由GTS统一处理全局事务的故障恢复与并发控制(RD中记录事务锁等信息,异步统一清理数据),对应用开发屏蔽事务处理的细节,从而提升应用的灵活性与数据的一致性。
业务补偿性会更灵活处理,需要开发之前也构建TCC的模式,加锁,扣减,释放锁等模式,这样能做到开发灵活控制。
参考: