我是传奇新手。
这是一个简单的场景:
- 用户点击“创建订单”:创建订单(首先保持其状态 = NEW)
- 用户填写完订单后,点击“保存”--> 状态现已提交
- 当另一个人检查订单并验证它时,必须发生一个过程。仅当调用其他一些服务并给予其 GO 时,该订单才会生效。
整个工作流程是:
新
->已提交
。- 从
SUBMITTED
,用户可以取消提交并将订单切换回NEW
。 - 验证可以将订单状态设置为
VALIDATED
或REJECTED
。 - 如果
已拒绝
,原始用户必须先修复其订单,然后才能再次进行验证。
因此,我需要避免在进行 VALIDATION
时订单回滚到 NEW
。
我的问题是,对于第 3 步,是否最好:
- 将订单状态更新为“待处理”,引发事件并启动传奇(具有其自己的状态以及流程的编排和例程 list )?
- 从订单聚合中删除状态并将其放入传奇中(因此传奇从步骤 1 开始)?该saga被命名为OrderSaga,封装了从开始到结束的所有流程,而不仅仅是需要外部服务的部分,即分布式事务)。
- 还有别的事吗? (感谢博客或 Google 群组邮件的链接)
谢谢
最佳答案
DDD
与域有关,因此首先您需要了解业务需求。那么,让我们看看规则是什么:
- 可以创建新订单
- 创建的订单可以在验证后提交
验证过程
可能需要一些时间,并且可以取消。如果取消订单可以重新提交验证过程
可以拒绝订单或接受订单- 如果订单被拒绝,可以更正后重新提交
- 如果订单被接受,则会被发送到下一个流程,并且无法提交或更正。
话虽这么说,我会将这两个过程(订单创建+创建和订单验证)分开。另外,我会在 OrderAggregate
上保留一个状态属性,用于强制执行其不变量。状态可以是:
新增
:订单创建后或验证取消或订单被拒绝后已提交
:提交验证后已发送
:在验证过程接受后。
仅当您需要其他行为时,您应该添加新状态。
OrderValidationSaga
还将有一个内部状态,用于跟踪从外部服务收到的外部响应。假设我们需要使用两个外部服务。状态将是一个具有两个属性的对象:service1IsOk
和 service2IsOk
。当任何服务表明订单无效时,无论内部进度如何,saga 都会拒绝该订单,并重置其内部状态。当服务显示“正常”时,传奇会在内部将其标记为“正常”,然后检查所有服务是否都正常。如果他们没问题,它会告诉聚合发送订单。然后聚合将订单标记为已发送
并发出一个事件。如果/当进程被取消时,saga 会重置其内部状态。
请注意,如果您使用CQRS
,那么所有状态更改都是通过发送命令和引发事件来完成的。 saga 将订阅事件并向聚合发送适当的命令。
有一篇好文章here .
关于domain-driven-design - Saga,存储聚合状态的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43551630/