前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Saga 事务

Saga 事务

原创
作者头像
Get
发布2024-03-25 22:35:20
1250
发布2024-03-25 22:35:20

Saga 事务

代码语言:java
复制
Saga 事务核心思想是将"长事务拆分为多个本地短事务",由 Saga 事务协调器协调,如果正常结束那就正常完成,
     如果"某个步骤失败,则根据相反顺序一次调用补偿操作"。
Saga 事务基本协议如下:
1、每个 Saga 事务由一系列幂等的有序子事务(sub-transaction) Ti 组成。
2、每个 Ti 都有对应的幂等补偿动作 Ci,补偿动作用于撤销 Ti 造成的结果。
TCC事务补偿机制有一个预留(Try)动作,相当于先报存一个草稿,然后才提交;
Saga事务没有预留动作,直接提交。

对于事务异常,Saga提供了两种恢复策略,分别如下:

1、向后恢复(backward recovery)

代码语言:java
复制
在执行事务失败时,补偿所有已完成的事务,是“一退到底”的方式。如下图:
从上图可知事务执行到了支付事务T3,但是失败了,因此事务回滚需要从C3,C2,C1依次进行回滚补偿。
对应的执行顺序为:T1,T2,T3,C3,C2,C1
这种做法的效果是撤销掉之前所有成功的子事务,使得整个 Saga 的执行结果撤销。

clipboard.png
clipboard.png

2、向前恢复(forward recovery)

代码语言:java
复制
也称之为:勇往直前,对于执行不通过的事务,会尝试重试事务,这里有一个假设就是每个子事务最终都会成功。
适用于必须要成功的场景,事务失败了重试,不需要补偿。

clipboard.png
clipboard.png

Saga事务有两种不同的实现方式,分别如下:

代码语言:java
复制
1、命令协调(Order Orchestrator)
2、事件编排(Event Choreographyo)

1、命令协调

代码语言:java
复制
中央协调器(Orchestrator,简称 OSO)以命令/回复的方式与每项服务进行通信,全权负责告诉每个参与者该做什么以及什么时候该做什么。整体流程如下图:
上图步骤如下:
事务发起方的主业务逻辑请求 OSO 服务开启订单事务
OSO 向库存服务请求扣减库存,库存服务回复处理结果。
OSO 向订单服务请求创建订单,订单服务回复创建结果。
OSO 向支付服务请求支付,支付服务回复处理结果。
主业务逻辑接收并处理 OSO 事务处理结果回复。
中央协调器必须事先知道执行整个订单事务所需的流程(例如通过读取配置)。如果有任何失败,它还负责通过向每个参与者发送命令来撤销之前的操作来协调分布式的回滚。
基于中央协调器协调一切时,回滚要容易得多,因为协调器默认是执行正向流程,回滚时只要执行反向流程即可。

clipboard.png
clipboard.png

2、事件编排

代码语言:java
复制
没有中央协调器(没有单点风险)时,每个服务产生并观察其他服务的事件,并决定是否应采取行动。
在事件编排方法中,第一个服务执行一个事务,然后发布一个事件。该事件被一个或多个服务进行监听,这些服务再执行本地事务并发布(或不发布)新的事件。
当最后一个服务执行本地事务并且不发布任何事件时,意味着分布式事务结束,或者它发布的事件没有被任何 Saga 参与者听到都意味着事务结束。
上图步骤如下:
事务发起方的主业务逻辑发布开始订单事件。
库存服务监听开始订单事件,扣减库存,并发布库存已扣减事件。
订单服务监听库存已扣减事件,创建订单,并发布订单已创建事件。
支付服务监听订单已创建事件,进行支付,并发布订单已支付事件。
主业务逻辑监听订单已支付事件并处理。
事件/编排是实现 Saga 模式的自然方式,它很简单,容易理解,不需要太多的代码来构建。如果事务涉及 2 至 4 个步骤,则可能是非常合适的。

clipboard.png
clipboard.png
代码语言:java
复制
优点
命令协调设计的优点如下:
服务之间关系简单,避免服务之间的循环依赖关系,因为 Saga 协调器会调用 Saga 参与者,但参与者不会调用协调器。
程序开发简单,只需要执行命令/回复(其实回复消息也是一种事件消息),降低参与者的复杂性。
易维护扩展,在添加新步骤时,事务复杂性保持线性,回滚更容易管理,更容易实施和测试。
事件/编排设计优点如下:
避免中央协调器单点故障风险。
当涉及的步骤较少服务开发简单,容易实现。
缺点
命令协调设计缺点如下:
中央协调器容易处理逻辑容易过于复杂,导致难以维护。
存在协调器单点故障风险。
事件/编排设计缺点如下:
服务之间存在循环依赖的风险。
当涉及的步骤较多,服务间关系混乱,难以追踪调测。
由于 Saga 模型中没有 Prepare 阶段,因此事务间不能保证隔离性。
当多个 Saga 事务操作同一资源时,就会产生更新丢失、脏数据读取等问题,这时需要在业务层控制并发,例如:在应用层面加锁,或者应用层面预先冻结资源。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档