赞
踩
本文是对《微服务架构设计模式》一书中的笔记整理。
所有的数据操作都在本地服务中完成,就是我们常说的ACID事务。
很多单体架构通常不适用严谨的ACID事务,而是使用较低的隔离级别来提高性能。
在微服务架构下,一个事务内包含的所有操作分散在多个服务中。
XA(两阶段提交)来保证参与方同时提交,或在失败时同时回滚。但是许多技术不支持XA标准的分布式事务,如MongoDB、RabbitMQ;它们本质上是同步的进程间通信,这会降低分布式系统可用性。
Saga是一种分布式事务的实现思路,将进程间的同步进程通信改为基于事件发布/订阅的异步通信。
可以通过补偿事务回滚的事务,其中只读步骤或者之后操作总是成功的步骤,不需要设计为可补偿性事务。
如果关键事务运行成功,那么Saga将一直运行到完成。关键事务不一定是可补偿性事务或者可重复性事务。它可以是最后一个可补偿性事务或者第一个可重复性事务。它是Saga执行过程的关键点。
在关键事务之后的事务,保证成功。
把Saga的决策和执行顺序逻辑分布式在Saga的每一个参与方中,它们互相通过交换事件来沟通。
把Saga的决策和执行顺序逻辑集中在一个Saga编排器中,Saga编排器可以是其中一个参与方。
简单的Saga可以使用协同式,但编排式通常是复杂Saga更好的选择。
不管使用哪种方式,事件发布都起着关键角色的作用,所以我们要保证可靠的事件通信。
第一个问题是要确保Saga参与方将更新其本地数据库和发布事件作为数据库事务的一部分。
第二个问题是Saga参与方必须能够将接收到的每个事件映射到自己的事件上。
编排器对其中某个参与方发出命令式消息,告诉这个参与方该做什么操作。当参与方完成操作后,会给编排器发送答复消息。编排器处理这个消息,并决定Saga的下一步操作是什么。
一个Saga没有读取更新,而是直接覆盖了另一个Saga的更改
一个事务或者一个Saga读取了尚未完成的Saga所做的更改
一个Saga的两个步骤读取相同的数据却获取了不同的结果,因为另一个Saga已经进行了更新。
由于每个Saga参与方的本地事务提交,所做的更改都会立即被其它Saga看到,可以认为Saga只满足ACD,不满足隔离性。
以一种能够防止异常或者最小化其对业务影响的方式来编写Saga。
在应用程序实现Saga时,可能使用多种对策,也可能使用基于XA的分布式事务,依据于业务风险评估。
语义锁是约定好的具有锁作用的标记,无强制约束力。
Saga的可补偿性事务会在其创建或更新的任何记录中设置标记,该标记表示该记录未提交且可能发生更改,该标记可以是阻止其它事务访问记录的锁,也可以是指示其它事务应该谨慎地处理该记录的一个警告。这个标记会被一个可重复性事务清除,表示Saga成功完成。或者通过补偿性事务清除,表示Saga发生了回滚。
案例:
Saga参与方遇到语义锁怎么办?此时可以直接返回失败并告诉客户端重试,或者阻塞等待,直到Saga释放了锁,这种情况下,应用程序要管理锁,做死锁检测。
它重新排序Saga的步骤,以最大限度地降低由于脏读而导致的业务风险。
Saga在更新之前重新读取记录,验证它是否未更改,然后更新记录,类似于乐观锁
它记录了对数据执行的操作,以便可以对它们重新进行排序,类似于MySQL的MVCC。
例如:create order Saga 与cancel order Saga同时执行,一个去要操作信用卡授权,一个要操作取消信用卡授权。若取消信用卡授权请求先到达,则记录在版本文件中,当信用卡授权信息再到达时,它会注意到已经收到了取消信用卡授权的请求,则跳过信用卡授权。
示例:创建订单,以下列举了核心类职责
方案1:Saga参与方发布包含相关ID的事件,该相关性ID使其参与方能够执行数据操作。
方案2:在事务消息中包含消息接收方所需的所有消息。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。