哈Ha! 我向您介绍克里斯·理查森(Chris Richardson)撰写的文章“模式:传奇(Pattern:Saga)”的翻译。
情况
有一个应用了“ 每个服务数据库”模式的应用程序。 现在,每个应用程序服务都有其自己的数据库。 一些业务交易一次涵盖多个服务,因此需要一种机制来确保这些服务之间的数据一致性。
例如:假设我们正在开发一个客户有信用额度的在线商店。 应用程序必须确保新订单不超过客户的信用额度。 由于订单和客户是不同的数据库,因此应用程序无法使用本地ACID事务。
问题
如何确保服务之间的数据一致性?
解决方案
跨越多个服务的每个业务交易都需要作为一个传奇来实现。
传奇是本地交易的集合。 每个本地事务都会更新数据库并发布消息或事件,从而启动传奇中的下一个本地事务。 如果事务失败(例如,由于违反业务规则),则该传奇事件将启动补偿事务,以回滚以前的本地事务所做的更改。

有两种方法可以协调Sagas:
- 编排-每个事务都会发布触发其他服务中的事务的事件。
- 编排-编排告诉参与者应该开始哪些事务。
示例:基于编舞的传奇

在使用基于编排的传奇的在线商店中,创建订单将包括以下步骤:
Order Service ( )
创建处于待处理状态(待定)的Order ()
,并发布OrderCreated ()
事件OrderCreated ()
Customer Service ( )
收到事件,并尝试为订单保留信用。 然后,它发布两个事件之一: CreditReserved ()
或CreditLimitExceeded ()
Order Service ( )
收到事件并将订单状态更改为已批准(已确认)或已取消(已取消)
示例:管弦乐队的传奇

在使用基于业务流程的传奇的在线商店中,创建订单将包括以下步骤:
Order Service ( )
创建处于待处理状态(待定)的Order ()
,并创建CreateOrderSaga ()
CreateOrderSaga ()
将ReserveCredit ()
命令发送给Customer Service ( )
Customer Service ( )
尝试为订单保留贷款并发回响应CreateOrderSaga ()
在Order Service ( )
接收响应并发送ApproveOrder ()
或RejectOrder ()
命令Order Service ( )
将Order Service ( )
状态更改为已批准(已确认)或已取消(已取消)
佐贺具有以下优点
- 允许应用程序在不使用分布式事务的情况下维护服务之间的数据一致性。
传奇有以下缺点
- 编程模型变得越来越复杂。 例如,开发人员必须设计补偿性交易,以还原在传奇中进行的更改。