本文总结:本文探讨了分布式事务的概念及解决方案。分布式事务指在分布式系统中多个服务协同完成业务时,需确保各服务事务同时成功或失败。针对这一问题,文章分析了多种解决方案:1)2PC/XA协议采用强一致性,通过两阶段提交实现;2)Seata的AT模式利用快照实现最终一致性;3)TCC模式通过Try-Confirm-Cancel三阶段处理事务;4)消息队列方案通过异步消息保证最终一致;5)Saga模式适用于长流程业务。选择方案时应根据业务需求,在强一致性和最终一致性间权衡,大多数场景可采用最终一致性方案。
分布式事务
分布式事务是什么呢?在分布式系统中,如果一个业务需要多个服务合作一起完成,并且每个服务都有事务,然后多个事务必须要同时成功或同时失败,这就是分布式事务。
分布式事务问题:多个服务之间各执行各的,比如下图:用户执行下单支付操作,下单支付成功,则购物车商品清空成功,这时假如我们的库存本来就是0,库存不足那库存扣减就会失败。也就是说下单服务和购物车服务都执行成功了,而库存执行失败,那这整个业务就出问题了只有前两个服务数据改变,最后一个不变,这就是分布式事务的问题。
解决思想:就是要让各个服务能感知到彼此的事务状态是否一致,解决分布式事务问题可以使用Seata提供的各种解决方案。
TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器:定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
有两种根本思路:1、强一致性(上帝视角进行指挥)2、最终一致性(事后约定进行补救)
分布式事务解决方案介绍
方案A:2PC/XA协议(强一致性)
例子:现场投票表决,全员举手才能通过。
第一阶段:准备(投票)
- 协调者(总指挥)问订单系统:“能创建订单吗?” 订单系统创建订单(但不提交),回复:“可以。”
- 同样问购物车、库存系统,都预执行并回复“可以”。
第二阶段:提交/回滚(宣布结果)
- 如果全部回复“可以”,协调者下令:“全体,正式提交!”
- 如果任何一个回复“不行”,协调者下令:“全体,回滚撤销!”
方案B:Seata中的AT模式(最终一致性)
例子:投票时先拍照存底,一旦失败就按照片复原。
第一阶段(拍照+预执行):每个系统在本地直接提交业务,但同时拍下数据修改前的“快照”(存入undo_log表)。
第二阶段:
- 成功:总指挥说成功,大家把“快照”删掉即可。
- 失败:总指挥说失败,大家根据
undo_log里的“快照”,自动执行反向SQL把数据恢复原样。
XA模式和AT的区别:
1、XA模式第一阶段不提交事务,锁定资源;AT模式第一阶段就直接提交,不锁定资源。
2、XA模式依赖于数据库机制事务回滚,而AT是基于快照进行回滚的
3、XA模式强一致性,AT模式最终一致性
方案C:TCC模式(最终一致性)
TCC模式初衷是强一致性,但可能会因为网络延迟、服务中断等外部因素问题,使它几乎不可能是强一致性,不得不降为最终一致性。
还是以订单服务--->购物车服务--->库存服务为例。
“预备、确认、取消”三步骤,这不是自动的,需要你为每个系统写三个方法:
1、Try(尝试/预备):冻结资源,而非真正扣除。
- 订单系统:订单状态置为“待确认”。
- 购物车系统:锁定(冻结)购物车,真实购物车商品数不变。
- 库存系统:对应商品预扣-1,标记为“待生效”。
2、Confirm(确认):Try都成功,才真正执行。
- 订单系统:状态变“成功”。
- 购物车系统:清空已冻结的购物车商品。
- 库存系统:将预扣商品变为“有效”。
3、Cancel(取消):任何一个Try失败,则释放资源。
- 订单系统:状态变“已取消”。
- 购物车系统:释放冻结的购物车商品。
- 库存系统:清除预扣减的库存。
TCC模式总结:性能好,隔离性强。但侵入性极大,需要写三倍代码,并且要处理幂等、空回滚等复杂问题。适用于金融、库存等严格要求的情景。
方案D:基于消息队列(最终一致性)
例子:发短信通知,直到对方确认为止。
核心是依靠可靠的消息传递来驱动下游事务。
流程:
1、订单系统和购物车系统在同一个数据库事务中完成,并同时向消息队列写入一条“订单已创建,请扣减库存”的消息(或插入本地消息表)。
2、事务提交。
3、消息队列保证把消息送达库存系统。
4、库存系统消费消息,为扣减商品数量。如果失败,消息队列会重试。
关键:消息的可靠存储和可靠投递。库存服务需要幂等设计(防止因重试导致库存扣减多次)。
消息队列总结:彻底解耦,高性能,高可用。但只保证最终一致性,设计时重点考虑消息可靠性、消费者幂等。
方案E:Saga模式(最终一致性)
例子:执行一个长长的清单,任何一步失败,就倒着往回取消。
适合流程非常长(分钟/小时级)的业务,比如快递(订机票、酒店)。
流程:
1、订单系统 -> 成功。
2、库存系统 -> 成功。
3、调用外部物流系统安排配送 ->失败!
补救:立即启动“反向操作”流程:
1、执行库存系统的补偿逻辑(回滚扣减)。
2、执行订单系统的补偿逻辑(取消订单)。
Saga总结:性能极高,适合长流程。但补偿逻辑设计复杂,且缺乏隔离性(可能脏读),需要业务能够容忍。
如何进行分布式事务解决方案选择?
一句话总结就是:
- XA/2PC:强一致但性能差,仅用于传统银行核心
- TCC模式:高性能最终一致,适用于金融、库存等需要资源预留的场景
- AT模式:无侵入最终一致,适合大多数普通业务
- Saga模式:长流程最终一致,适合旅行预订、保险理赔
- 消息队列:异步最终一致,适合通知、数据同步等解耦场景
核心原则:99%的业务场景都可以接受最终一致性,因此分布式事务的重点不是追求强一致,而是在接受最终一致的前提下,根据具体业务特点选择最合适的方案。