domain-driven-design - Saga,存储聚合状态的位置

标签 domain-driven-design saga

我是传奇新手。

这是一个简单的场景:

  1. 用户点击“创建订单”:创建订单(首先保持其状态 = NEW)
  2. 用户填写完订单后,点击“保存”--> 状态现已提交
  3. 当另一个人检查订单并验证它时,必须发生一个过程。仅当调用其他一些服务并给予其 GO 时,该订单才会生效。

整个工作流程是:

  • -> 已提交
  • SUBMITTED,用户可以取消提交并将订单切换回NEW
  • 验证可以将订单状态设置为VALIDATEDREJECTED
  • 如果已拒绝,原始用户必须先修复其订单,然后才能再次进行验证。

因此,我需要避免在进行 VALIDATION 时订单回滚到 NEW

我的问题是,对于第 3 步,是否最好:

  • 将订单状态更新为“待处理”,引发事件并启动传奇(具有其自己的状态以及流程的编排和例程 list )?
  • 从订单聚合中删除状态并将其放入传奇中(因此传奇从步骤 1 开始)?该saga被命名为OrderSaga,封装了从开始到结束的所有流程,而不仅仅是需要外部服务的部分,即分布式事务)。
  • 还有别的事吗? (感谢博客或 Google 群组邮件的链接)

谢谢

最佳答案

DDD 与域有关,因此首先您需要了解业务需求。那么,让我们看看规则是什么:

  1. 可以创建新订单
  2. 创建的订单可以在验证后提交
  3. 验证过程可能需要一些时间,并且可以取消。如果取消订单可以重新提交
  4. 验证过程可以拒绝订单或接受订单
  5. 如果订单被拒绝,可以更正后重新提交
  6. 如果订单被接受,则会被发送到下一个流程,并且无法提交或更正。

话虽这么说,我会将这两个过程(订单创建+创建和订单验证)分开。另外,我会在 OrderAggregate 上保留一个状态属性,用于强制执行其不变量。状态可以是:

  1. 新增:订单创建后或验证取消或订单被拒绝后
  2. 已提交:提交验证后
  3. 已发送:在验证过程接受后。

仅当您需要其他行为时,您应该添加新状态。

OrderValidationSaga 还将有一个内部状态,用于跟踪从外部服务收到的外部响应。假设我们需要使用两个外部服务。状态将是一个具有两个属性的对象:service1IsOkservice2IsOk。当任何服务表明订单无效时,无论内部进度如何,saga 都会拒绝该订单,并重置其内部状态。当服务显示“正常”时,传奇会在内部将其标记为“正常”,然后检查所有服务是否都正常。如果他们没问题,它会告诉聚合发送订单。然后聚合将订单标记为已发送并发出一个事件。如果/当进程被取消时,saga 会重置其内部状态。

请注意,如果您使用CQRS,那么所有状态更改都是通过发送命令和引发事件来完成的。 saga 将订阅事件并向聚合发送适当的命令。

有一篇好文章here .

关于domain-driven-design - Saga,存储聚合状态的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43551630/

相关文章:

domain-driven-design - 具有标识的值对象

architecture - 我的身份服务器应该拥有用户配置文件吗?

javascript - Redux-Saga 无法正确读取来自 fetch api 的响应

c# - 如何在 MassTransit 3.0 中使用分散/聚集模式实现传奇

javascript - 如何使用 eventChannel 将函数传递给 redux-saga 中的回调

design-patterns - 将两个域对象组合到一个 View 中

design-patterns - 层的设计理念是人为的吗?

oop - DDD 书,埃里克·埃文斯 : What is meant by "The FACTORY should be abstracted to the type desired rather than the concrete class(es) created."?

c# - NServiceBus Saga 没有注册 IPersistTimeouts 组件

javascript - 如何从gradle调用任意方法?