文章目录
- 1. 什么是分布式事务
- 2. CAP 理论
- 4. 分布式事务解决方案
- 5. Seata
前面两篇文章主要介绍了Seata
环境搭建和Seata
基本使用,这篇来学习下分布式事务原理
1. 什么是分布式事务
分布式架构对应的是单体架构。随着业务复杂度和用户体验要求提高,单体架构已经无法满足互联网产品架构的需求,逐渐演变出了分布式架构
分布式架构下,需要服务与服务之间的远程协作才能完成一个用户操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务,例如创建订单减库存事务,银行转账事务等都是分布式事务
分布式架构中,每个服务负责不同的业务,各服务之间互相调用:
2. CAP 理论
2.1 CAP理论
CAP
原则又叫 CAP
定理,指的是在一个分布式系统中,不可能同时满足以下三点:一致性(C
)、可用性(A
)、分区容错性(P
)
- 一致性(
Consistency
)
简单的说:要求每个人看到的数据必须一致。
指强一致性,在写操作完成后开始的任何读操作都必须返回该值,也就是说,在一致性系统中,一旦客户端将值写入任何一台服务器并获得响应,那么之后客户端从其他任何服务器读取的都是刚写入的数据。
一致性保证了不管向哪台服务器写入数据,其他的服务器能实时同步数据
- 可用性(
Availability
)
简单的说:要求系统任何时候都可用,哪怕每个用户看到的数据不一样
可用性是指:每次向未崩溃的节点发送请求,总能保证收到响应数据(允许不是最新数据)
- 分区容错性(
Partition tolerance
)
部分服务器因网络问题,业务依然能够继续运行
一个分布式系统里面,节点组成的网络本来应该是连通的,然而可能因为一些故障,使有些节点之间不连通了,整个网络就分成了几块区域,数据就散布在了这些不连通的区域中,这就叫分区。
分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
2.2 A 和 C 之间取舍
CAP
理论告诉我们,一个分布式系统不可能同时满足这三个需求,最多只能同时满足其中的两项。
在分布式系统中,如果选择了 CA
,舍弃了 P
,说白了就是一个单体架构,这是不允许的,所以必须满足 CAP
中的 P
,此时只能在 C/A
之间作出取舍。
举个例子,来说明CAP理论的场景:
淘宝是分布式架构,首先肯定要满足分区容错性(P),在购物时,淘宝肯定要保证系统的可用性(A),因为它不可能要求对于商品的点赞数要求数据强一致性(C),数据的强一致性要求每个用户看到的数据必须一致。如果要求数据的强一致性,那系统应该早崩了。
2.3 一致性分类
在分布式架构中,CAP
理论只能在 C
、A
之间选择,在分布式事务的最终解决方案中一般选择牺牲一致性来获取可用性和分区容错性
这里的 “牺牲一致性” 并不是完全放弃数据的一致性,而是放弃强一致性而换取弱一致性,也就是说在一段时间后,数据的一致性会得到保证,数据可以在系统没有压力的时候慢慢恢复。
一致性可以分为以下三种:
- 强一致性
系统中的某个数据被成功更新后,后续任何对该数据的读取操作都将得到更新后的值,简言之,在任意时刻,所有节点中的数据是一样的。
一个集群需要对外部提供强一致性,所以只要集群内部某一台服务器的数据发生了改变,那么就需要等待集群内其他服务器的数据同步完成后,才能正常的对外提供服务
保证了强一致性,务必会损耗可用性
- 弱一致性
系统中的某个数据被更新后,后续对该数据的读取操作可能得到更新后的值,也可能是更改前的值,但即使过了不一致时间窗口这段时间后,后续对该数据的读取也不一定是最新值。
所以说,可以理解为数据更新后,如果能容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。
例如 12306 买火车票,虽然最后看到还剩下几张余票,但是只要选择购买就会提示没票了,这就是弱一致性。
- 最终一致性
不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据在一段时间后,节点间的数据会最终达到一致状态。
4. 分布式事务解决方案
在分布式架构下,每个服务节点只知晓自己操作的失败或者成功,无法得知其他节点的状态。
当一个事务跨多个服务节点时,为了保持事务的原子性与一致性,而引入一个协调者来统一掌控所有参与者的操作结果,并指示它们是否要把操作结果进行真正的提交或者回滚。
4.1 二阶段提交(2PC)
二阶段提交协议(Two-phase Commit
,即 2PC
)是常用的分布式事务解决方案,即将事务的提交过程分为两个阶段来进行处理。两个阶段分别为:准备阶段、提交阶段
参与的角色:
- 事务协调者(事务管理器):事务的发起者
- 事务参与者(资源管理器):事务的执行者
4.1.1 准备阶段
这是两阶段的第一段,这一阶段只是准备阶段,由事务的协调者发起询问参与者是否可以提交事务,但是这一阶段并未提交事务,流程图如下图:
- 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待答复
- 各参与者执行事务操作,将
undo
和redo
信息记入事务日志中(但不提交事务) - 如参与者执行成功,给协调者反馈同意,否则反馈中止
4.1.2 提交阶段
提交执行阶段属于 2PC
的第二阶段,协调者发起正式提交事务的请求,当所有参与者都回复同意时,则意味着完成事务,流程图如下:
- 协调者节点向所有参与者节点发出正式提交 (
commit
) 的请求 - 参与者节点正式完成操作,并释放在整个事务期间内占用的资源
- 参与者节点向协调者节点发送
ack
完成消息 - 协调者节点收到所有参与者节点反馈的
ack
完成消息后,完成事务
但是,如果任意一个参与者节点在第一阶段返回的消息为终止,或者协调者节点在第一阶段的询问超时之前无法获取所有参与者节点的响应消息时,那么这个事务将会被回滚。
回滚的流程图如下:
- 协调者节点向所有参与者节点发出回滚操作 (
rollback
) 的请求 - 参与者节点利用阶段
1
写入的undo
信息执行回滚,并释放在整个事务期间内占用的资源 - 参与者节点向协调者节点发送
ack
回滚完成消息 - 协调者节点收到所有参与者节点反馈的
ack
回滚完成消息后,取消事务
二阶段提交的事务正常提交的完整流程如下图:
二阶段提交事务回滚的完整流程如下图:
4.1.3 二阶段提交优缺点
2PC
看起来确实能够提供原子性的操作,但二阶段提交还是有几个缺点:
- 性能问题:执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态
- 可靠性问题:参与者发生故障,协调者需要给每个参与者额外指定超时机制,超时后整个事务失败,协调者发生故障,参与者会一直阻塞下去,需要额外的备机进行容错
- 数据一致性问题:二阶段无法解决的问题:协调者在发出
commit
消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交 - 实现复杂:牺牲了可用性,对性能影响较大,不适合高并发高性能场景
2PC
的优点:尽量保证了数据的强一致,适合对数据强一致要求很高的关键项目
4.2 三阶段提交(3PC)
三阶段提交,是二阶段提交的改进版本,三阶段提交有两个改动点
- 在协调者和参与者中都引入超时机制
- 在第一阶段和第二阶段中插入一个准备阶段,保证了在最后提交阶段之前各参与节点的状态是一致的
也就是说,除了引入超时机制之外,3PC
把 2PC
的准备阶段再次一分为二。这样三阶段提交就有 CanCommit
、PreCommit
、DoCommit
三个阶段,处理流程如下:
4.2.1 CanCommit 阶段
3PC
的 CanCommit
阶段其实和 2PC
的准备阶段很像,协调者向参与者发送 commit
请求,参与者如果可以提交就返回 Yes
响应,否则返回 No
响应
- 事务询问:协调者向所有参与者发出包含事务内容的
canCommit
请求,询问是否可以提交事务,并等待所有参与者答复 - 响应反馈:参与者收到
canCommit
请求后,如果认为可以执行事务操作,则反馈yes
并进入预备状态,否则反馈no
CanCommit
阶段流程如下图:
4.2.2 PreCommit 阶段
协调者根据参与者的反应情况来决定是否可以进行事务的 PreCommit
操作,根据响应情况,有以下两种可能。
假如所有参与者均反馈 yes
,协调者预执行事务
-
发送预提交请求 :协调者向参与者发送
PreCommit
请求,并进入准备阶段 -
事务预提交 :参与者接收到
PreCommit
请求后,会执行事务操作,并将undo
和redo
信息记录到事务日志中(但不提交事务) -
响应反馈 :如果参与者成功的执行了事务操作,则返回
ACK
响应,同时开始等待最终指令
假如有任何一个参与者向协调者发送了 No
响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。
-
发送中断请求 :协调者向所有参与者发送
abort
请求 -
中断事务 :参与者收到来自协调者的
abort
请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断
4.2.3 doCommit 阶段
该阶段进行真正的事务提交,也可以分为以下两种情况
进入阶段 3 后,无论协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出的 doCommit 请求或 abort 请求。此时,参与者都会在等待超时之后,继续执行事务提交。
执行提交
-
发送提交请求:协调接收到参与者发送的
ACK
响应,那么它将从预提交状态进入到提交状态,并向所有参与者发送doCommit
请求 -
事务提交:参与者接收到
doCommit
请求之后,执行正式的事务提交,并在完成事务提交之后释放所有事务资源 -
响应反馈:事务提交完之后,向协调者发送
ack
响应 -
完成事务:协调者接收到所有参与者的
ack
响应之后,完成事务
中断事务:任何一个参与者反馈 no
,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务:
-
发送中断请求:如果协调者处于工作状态,向所有参与者发出
abort
请求 -
事务回滚:参与者接收到
abort
请求之后,利用其在阶段二记录的undo
信息来执行事务的回滚操作,并在完成回滚之后释放所有的事务资源 -
反馈结果:参与者完成事务回滚之后,向协调者反馈
ACK
消息 -
中断事务:协调者接收到参与者反馈的
ACK
消息之后,执行事务的中断
4.2.4 三阶段提交优缺点
优点:相比二阶段提交,三阶段提交降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段 3 中协调者出现问题时,参与者会继续提交事务
缺点:数据不一致问题依然存在,当在参与者收到 preCommit
请求后等待 doCommit
指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致
4.3 TCC (事务补偿)
TCC
(Try Confirm Cancel
)方案是一种应用层面侵入业务的两阶段提交。是目前最火的一种柔性事务方案,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。
TCC
分为两个阶段,分别如下:
第一阶段:Try
,主要是对业务系统做检测及资源预留 (加锁,锁住资源)
第二阶段:本阶段根据第一阶段的结果,决定是执行 confirm
还是 cancel
-
Confirm
(确认):执行真正的业务(执行业务,释放锁) -
Cancel
(取消):是预留资源的取消(出问题,释放锁)
为了方便理解,下面以电商下单为例进行方案解析,这里把整个过程简单分为扣减库存,订单创建 2 个步骤,库存服务和订单服务分别在不同的服务器节点上。
假设商品库存为 100
,购买数量为2
,这里检查和更新库存的同时,冻结用户购买数量的库存,同时创建订单,订单状态为待确认。
4.3.1 Try 阶段
TCC
机制中的 Try
仅是一个初步操作,它和后续的确认一起才能真正构成一个完整的业务逻辑,这个阶段主要完成:
- 完成所有业务检查( 一致性 )
- 预留必须业务资源( 准隔离性 )
-
Try
尝试执行业务
4.3.2 Confirm / Cancel 阶段
根据 Try
阶段服务是否全部正常执行,继续执行确认操作(Confirm
)或取消操作(Cancel
)
Confirm
和 Cancel
操作满足幂等性,如果 Confirm
或 Cancel
操作执行失败,将会不断重试直到执行完成
Confirm
:当 Try
阶段服务全部正常执行, 执行确认业务逻辑操作,业务如下图:
这里使用的资源一定是 Try
阶段预留的业务资源。在 TCC
事务机制中认为,如果在 Try
阶段能正常的预留资源,那 Confirm
一定能完整正确的提交
Confirm
阶段也可以看成是对 Try
阶段的一个补充,Try+Confirm
一起组成了一个完整的业务逻辑
Cancel
:当 Try
阶段存在服务执行失败, 进入 Cancel
阶段,业务如下图:
Cancel
取消执行,释放 Try
阶段预留的业务资源,上面的例子中,Cancel
操作会把冻结的库存释放,并更新订单状态为取消。
4.3.3 最终一致性保证
-
TCC
事务机制以初步操作(Try
)为中心的,确认操作(Confirm
)和取消操作(Cancel
)都是围绕初步操作(Try
)而展开。因此,Try
阶段中的操作,其保障性是最好的,即使失败,仍然有取消操作(Cancel
)可以将其执行结果撤销 -
Try
阶段执行成功并开始执行Confirm
阶段时,默认Confirm
阶段是不会出错的。也就是说只要Try
成功,Confirm
一定成功(TCC
设计之初的定义) -
Confirm
与Cancel
如果失败,由TCC
框架进行重试补偿; - 存在极低概率在
CC
环节彻底失败,则需要定时任务或人工介入
4.3.4 方案总结
TCC
事务机制相对于传统事务机制(X/Open XA
),TCC
事务机制相比于上面介绍的 XA
事务机制,有以下优点:
- 性能提升:具体业务来实现控制资源锁的粒度变小,不会锁定整个资源;
- 数据最终一致性:基于
Confirm
和Cancel
的幂等性,保证事务最终完成确认或者取消,保证数据的一致性 - 可靠性:解决了
XA
协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动管理器也变成多点,引入集群。
缺点:TCC
的 Try
、Confirm
和 Cancel
操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本
4.4 本地消息表
本地消息表核心思路是:将分布式事务拆分成本地事务进行处理
角色:事务主动方、事务被动方
通过在事务主动发起方额外新建事务消息表,事务发起方处理业务和记录事务消息在本地事务中完成,轮询事务消息表的数据发送事务消息,事务被动方基于消息中间件消费事务消息表中的事务
这样可以避免以下两种情况导致的数据不一致性:
- 业务处理成功、事务消息发送失败
- 业务处理失败、事务消息发送成功
整体的流程如下图:
上图中整体的处理步骤如下:
- ①:事务主动方在同一个本地事务中处理业务和写消息表操作
- ②:事务主动方通过消息中间件,通知事务被动方处理事务通知事务待消息。消息中间件可以基于
Kafka
、RocketMQ
消息队列,事务主动方主动写消息到消息队列,事务消费方消费并处理消息队列中的消息 - ③:事务被动方通过消息中间件,通知事务主动方事务已处理的消息
- ④:事务主动方接收中间件的消息,更新消息表的状态为已处理
一些必要的容错处理如下:
- 当 ① 处理出错,由于还在事务主动方的本地事务中,直接回滚即可
- 当 ②、③ 处理出错,由于事务主动方本地保存了消息,只需要轮询消息重新通过消息中间件发送,事务被动方重新读取消息处理业务即可
- 如果是业务上处理失败,事务被动方可以发消息给事务主动方回滚事务
- 如果事务被动方已经消费了消息,事务主动方需要回滚事务的话,需要发消息通知事务主动方进行回滚事务
优点
- 从应用设计开发的角度实现了消息数据的可靠性,消息数据的可靠性不依赖于消息中间件,弱化了对
MQ
中间件特性的依赖 - 方案轻量,容易实现
缺点
- 与具体的业务场景绑定,耦合性强,不可公用
- 消息数据与业务数据同库,占用业务系统资源
- 业务系统在使用关系型数据库的情况下,消息服务性能会受到关系型数据库并发性能的局限
4.5 MQ 事务方案(可靠消息事务)
基于 MQ
的分布式事务方案其实是对本地消息表的封装,将本地消息表放在 MQ
内部,其他方面的协议基本与本地消息表一致。
MQ
事务方案整体流程和本地消息表的流程很相似,如下图:
从上图可以看出和本地消息表方案唯一不同就是将本地消息表存在了 MQ
内部,而不是业务数据库中
那么 MQ
内部的处理尤为重要,下面主要基于 RocketMQ4.3
之后的版本介绍 MQ
的分布式事务方案
在本地消息表方案中,保证事务主动方发写业务表数据和写消息表数据的一致性是基于数据库事务,RocketMQ
的事务消息相对于普通 MQ
提供了 2PC
的提交接口,方案如下:
正常情况:事务主动方发消息
这种情况下,事务主动方服务正常,没有发生故障,发消息流程如下:
- 步骤①:发送方向
MQ
服务端 (MQ Server
) 发送half
消息 - 步骤②:
MQ Server
将消息持久化成功之后,向发送方ack
确认消息已经发送成功 - 步骤③:发送方开始执行本地事务逻辑;
- 步骤④:发送方根据本地事务执行结果向
MQ Server
提交二次确认(commit
或是rollback
) - 步骤⑤:
MQ Server
收到commit
状态则将半消息标记为可投递,订阅方最终将收到该消息,MQ Server
收到rollback
状态则删除半消息,订阅方将不会接受该消息
异常情况:事务主动方消息恢复
在断网或者应用重启等异常情况下,图中 4
提交的二次确认超时未到达 MQ Server
,此时处理逻辑如下:
- 步骤⑤:
MQ Server
对该消息发起消息回查 - 步骤⑥:发送方收到消息回查后,需要检查对应消息的本地事务执行的最终结果
- 步骤⑦:发送方根据检查得到的本地事务的最终状态再次提交二次确认
- 步骤⑧:
MQ Server
基于commit/rollback
对消息进行投递或者删除
优点:
相比本地消息表方案,MQ
事务方案优点是:
- 消息数据独立存储 ,降低业务系统与消息系统之间的耦合
- 吞吐量大于使用本地消息表方案
缺点
- 一次消息发送需要两次网络请求 (
half
消息 +commit/rollback
消息) - 业务处理服务需要实现消息状态回查接口
4.6 最大努力通知
最大努力通知也称为定期校对,是对 MQ
事务方案的进一步优化。它在事务主动方增加了消息校对的接口,如果事务被动方没有接收到消息,此时可以调用事务主动方提供的消息校对的接口主动获取
最大努力通知的整体流程如下图:
在可靠消息事务中,事务主动方需要将消息发送出去,并且消息接收方成功接收,这种可靠性发送是由事务主动方保证的
但是最大努力通知,事务主动方尽最大努力(重试,轮询…)将事务发送给事务接收方,但是仍然存在消息接收不到,此时需要事务被动方主动调用事务主动方的消息校对接口查询业务消息并消费,这种通知的可靠性是由事务被动方保证的
最大努力通知适用于业务通知类型,例如微信交易的结果,就是通过最大努力通知方式通知各个商户,既有回调通知,也有交易查询接口
4.7 Saga 事务
Saga
事务核心思想是:将长事务拆分为多个本地短事务,由 Saga
事务协调器协调,如果正常结束那就正常完成,如果某个步骤失败,则根据相反顺序一次调用补偿操作
4.7.1 Saga基本协议
Saga
事务基本协议如下:
- 每个
Saga
事务由一系列幂等的有序子事务(sub-transaction
)Ti
组成 - 每个
Ti
都有对应的幂等补偿动作Ci
,补偿动作用于撤销Ti
造成的结果
TCC
事务补偿机制有一个预留 (Try
) 动作,相当于先报存一个草稿,然后才提交,事务没有预留动作,直接提交
对于事务异常,Saga
提供了两种恢复策略,分别为:向后恢复、向前恢复
4.7.2 向后恢复 (backward recovery)
在执行事务失败时,补偿所有已完成的事务,是“一退到底”的方式,如下图:
从上图可知事务执行到了支付事务T3
,但是失败了,因此事务回滚需要从C3,C2,C1
依次进行回滚补偿
对应的执行顺序为:T1,T2,T3,C3,C2,C1
这种做法的效果是撤销掉之前所有成功的子事务,使得整个 Saga
的执行结果撤销
4.7.3 向前恢复 (forward recovery)
对于执行不通过的事务,会尝试重试事务,这里有一个假设就是每个子事务最终都会成功,流程如下图:
适用于必须要成功的场景,事务失败了重试,不需要补偿
4.7.4 Saga事务实现方式
Saga
事务有两种不同的实现方式,分别如下:命令协调(Order Orchestrator
)、事件编排(Event Choreographyo
)
4.7.4.1 命令协调
*协调器(Orchestrator
,简称 OSO
)以命令/回复的方式与每项服务进行通信,全权负责告诉每个参与者该做什么以及什么时候该做什么。整体流程如下图:
上图步骤如下:
- 事务发起方的主业务逻辑请求
OSO
服务开启订单事务 -
OSO
向库存服务请求扣减库存,库存服务回复处理结果 -
OSO
向订单服务请求创建订单,订单服务回复创建结果 -
OSO
向支付服务请求支付,支付服务回复处理结果 - 主业务逻辑接收并处理
OSO
事务处理结果回复
*协调器必须事先知道执行整个订单事务所需的流程(例如通过读取配置)。如果有任何失败,它还负责通过向每个参与者发送命令来撤销之前的操作来协调分布式的回滚
基于*协调器协调一切时,回滚要容易得多,因为协调器默认是执行正向流程,回滚时只要执行反向流程即可
4.7.4.2 事件编排
没有*协调器(没有单点风险)时,每个服务产生并观察其他服务的事件,并决定是否应采取行动
在事件编排方法中,第一个服务执行一个事务,然后发布一个事件。该事件被一个或多个服务进行监听,这些服务再执行本地事务并发布(或不发布)新的事件
当最后一个服务执行本地事务并且不发布任何事件时,意味着分布式事务结束,或者它发布的事件没有被任何 Saga
参与者听到都意味着事务结束
上图步骤如下:
- 事务发起方的主业务逻辑发布开始订单事件
- 库存服务监听开始订单事件,扣减库存,并发布库存已扣减事件
- 订单服务监听库存已扣减事件,创建订单,并发布订单已创建事件
- 支付服务监听订单已创建事件,进行支付,并发布订单已支付事件
- 主业务逻辑监听订单已支付事件并处理
4.7.5 Saga事务优缺点
4.7.5.1 优点
命令协调设计的优点如下:
- 服务之间关系简单,避免服务之间的循环依赖关系,因为
Saga
协调器会调用Saga
参与者,但参与者不会调用协调器 - 程序开发简单,只需要执行命令/回复(其实回复消息也是一种事件消息),降低参与者的复杂性
- 易维护扩展,在添加新步骤时,事务复杂性保持线性,回滚更容易管理,更容易实施和测试
事件编排设计优点如下:
- 避免*协调器单点故障风险
- 当涉及的步骤较少服务开发简单,容易实现
4.7.5.2 缺点
命令协调设计缺点如下:
- *协调器容易处理逻辑容易过于复杂,导致难以维护
- 存在协调器单点故障风险。
事件编排设计缺点如下:
- 服务之间存在循环依赖的风险
- 当涉及的步骤较多,服务间关系混乱,难以追踪调测
由于 Saga 模型中没有 Prepare 阶段,因此事务间不能保证隔离性。
当多个 Saga
事务操作同一资源时,就会产生更新丢失、脏数据读取等问题,这时需要在业务层控制并发,例如:在应用层面加锁,或者应用层面预先冻结资源
4.8 总结
总结一下各个方案的常见的使用场景:
-
2PC/3PC
:依赖于数据库,能够很好的提供强一致性和强事务性,但相对来说延迟比较高,比较适合传统的单体应用,在同一个方法中存在跨库操作的情况,不适合高并发和高性能要求的场景; -
TCC
:适用于执行时间确定且较短,实时性要求高,对数据一致性要求高,比如互联网金融企业最核心的三个服务:交易、支付、账务; - 本地消息表/
MQ
事务:都适用于事务中参与方支持操作幂等,对一致性要求不高,业务上能容忍数据不一致到一个人工检查周期,事务涉及的参与方、参与环节较少,业务上有对账/校验系统兜底; -
Saga
事务:由于Saga
事务不能保证隔离性,需要在业务层控制并发,适合于业务场景事务并发操作同一资源较少的情况。Saga
相比缺少预提交动作,导致补偿动作的实现比较麻烦,例如业务是发送短信,补偿动作则得再发送一次短信说明撤销,用户体验比较差。Saga
事务较适用于补偿动作容易处理的场景。
5. Seata
上面介绍了这么多的分布式事务的理论知识,Seata
就是理论知识的落地实现。
Seata
是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata
将为用户提供了 AT
、TCC
、SAGA
和 XA
事务模式,为用户打造一站式的分布式解决方案。
看完上面,再去看看Seata
官方文档吧
https://seata.io/zh-cn/docs/overview/what-is-seata.html