与我一起学习微服务架构设计模式4—使用Saga管理事务

微服务下的事务管理

微服务架构下的事务往往需要横跨多个服务,每个服务都有属于自己的私有数据库。传统的分布式事务管理并不是合适选择,需要使用Saga机制。

微服务架构对分布式事务的需求

每个服务都有自己的私有数据库,需要一种机制来保障多数据库环境下的数据一致性。

分布式事务的挑战

分布式事务管理的事实标准是XA,它采用两阶段提交保证事务中所有参与方同时完成提交,或失败时同时回滚。应用程序的整个技术栈需要满足XA标准。

问题:

  • 许多新技术,如NoSQL数据库,Kafka等消息代理不支持XA标准。

  • 其本质上都是同步进程间通信,这会降低分布式系统的可用性。

使用Sage模式维护数据一致性

Saga由一连串的本地事务组成,每一个本地事务负责更新它所在服务的私有库,使用异步消息来协调一系列本地事务。启动Saga时,协调逻辑必须选择并通知第一个Saga参与方执行本地事务,一旦事务完成,Saga协调选择并调用下一个Saga参与方。直到执行完所有步骤。

挑战:

  • 缺乏事务的隔离性

  • 发生错误时的回滚更改

Saga使用补偿事务来回滚所做出的改变

当Saga的步骤因违反业务规则而失败时,Saga必须通过执行补偿事务显式撤销先前所做的更新,它按照正常事务的反向顺序来执行补偿事务。

Saga的协调模式

协同式Saga

把Saga的决策和执行顺序逻辑分布在Saga的每一个参与方中,它们通过交换事件的方式进行沟通。

Saga实现基于发布/订阅的通信时考虑的问题:可靠的事件通信。

1、基于协同的Saga每一步都会更新数据库并发布一个事件,确保两者是原子的。考虑使用事务性消息

2、确保Saga参与方能够将接收到每个事件映射到自己的数据。解决方案是让Saga参与方发布包含相关性ID的事件

好处:简单、松耦合

弊端:

  • 更难理解,逻辑分布在每个服务实现

  • 服务之间循环依赖关系

  • 紧耦合风险,每个参与方都需要订阅所有影响它们的事件

编排式Saga

把Saga的决策和执行顺序逻辑集中在一个Saga编排器类中。Saga编排器发出命令式消息给各个Saga参与方,指示这些参与方完成具体操作。参与方完成后,会给编排器发送一个答复消息。

状态机是建模Saga编排器的一个好方法。

服务必须使用事务性消息,以便自动更新数据库并发布消息。

好处:

  • 更简单的依赖关系,不会有循环依赖

  • 较少的耦合,只实现供编排器调用的API

  • 改善关注点隔离,简化业务逻辑

弊端: 

在编排器中存在集中过多的业务逻辑风险,可以通过设计只负责排序的编排器来避免此问题,并且不包含任何其他业务逻辑。

解决隔离问题

Saga缺乏ACID事务的隔离属性,可能导致数据库异常。

  • 丢失更新:一个Saga覆盖另一个Saga所做的更新。

  • 脏读:一个事务或者一个Saga读取了尚未完成的Saga所做的更新。

  • 模糊或不可重复读:一个Saga的两个不同步骤读取相同的数据却获得了不同的结果,因为另一个Saga已经进行了更新。

Saga的结构

可补偿性事务: 可以使用补偿事务回滚的事务

关键性事务: Saga执行过程的关键点。若执行成功,Saga将一直运行到完成。

可重复性事务: 在关键性事务之后的事务,保证成功。

对策

语义锁 

应用程序级的锁。可补偿性事务会在其创建或更新的记录中设置标志(如Order的*_PENDING状态),表示该记录未提交且可能发生更改。它会被可重复事务清除,表示Saga完成,或通过补偿事务清除,表示Saga发生回滚。

两种方法处理锁定情况:

1、执行失败且告诉客户端重试,易于实现,但客户端必须实现重试逻辑,更复杂点。

2、使其阻塞,直到Saga释放语义锁。这使得更新相同操作的Saga被序列化,减少了编程量,消除了客户端重试的负担,但应用必须管理锁,实现死锁检测算法。

交换式更新 

把更新操作设计成可以按任何顺序执行的,即可交换的。如账户的借记和贷记。

悲观视图

重新排序Saga的步骤,以最大限度降低脏读导致的业务风险

重读值

防止丢失更新,以在覆盖数据之前验证它是否保持不变。未更改,则更新数据,若已更改,则Saga中止且可能重新启动。

版本文件

将更新记录下来,以便对它们重新排序。

业务风险评级

使用每个请求的业务风险来动态选择并发机制。如使用Saga执行低风险请求,使用分布式事务执行高风险请求(如涉及大量资金)

框架

Eventuate Tram Saga:一个用于编写Saga编排器的框架。

java达人

ID:drjava

(长按或扫码识别)

感谢你的阅读,下面是一个抽奖链接按钮,10月27日晚上开奖,共5个红包,写文不易,感谢大家支持。

感谢大家一直以来的阅读、在看和转发,点我参与抽奖!点我参与抽奖!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值