佐贺依赖过去的事件

时间:2011-09-08 10:56:39

标签: domain-driven-design cqrs saga

我有一个问题,如何处理决策的传奇 取决于在创建传奇之前发布的事件。

这是一个说明我的问题的例子:

想象一下,我有一个CustomerAR和一个OrderAR。当customerAR是 创建一个验证过程启动,该过程的结果是 客户可以免费支付的订单金额 授权。我不会详细介绍这个过程,因为 它脱离了背景。计算金额时,将发送命令 使用计算的金额和CustomerAR到CustomerAR 发布具有该值的事件(CustomerMaxOrderAmountEvent)。所以 非常好。

几周后,客户下了订单。 OrderAR是 创建并启动我的OrderSaga。传奇一直等到命令 完全创建,然后必须做出决定,如果它需要发送 该订单的AutorizationCommand。要做出决定,必须这样做 知道CustomerMaxOrderAmountEvent是否已发布且值是否为 数量。通常OrderSaga也会订阅 CustomerMaxOrderAmountEvent,但问题是这个事件永远不会 之所以发生,是因为它过去已经发生过。

我应该如何处理这件事。我应该查询读模型以了解 值,我应该发送命令来获取值,我应该做一个 如果我重播所有历史事件,请参考CustomerAR 这个传奇因此他已经了解了历史。

更新

请注意,这不是关于这个具体例子的概念。这个例子纯粹是为了澄清问题:“2个不相关的聚合根不属于同一个有界语境。”

感谢您的帮助。

梅尔文

2 个答案:

答案 0 :(得分:1)

我会选择更简单的解决方案 - 只需将此信息(例如以HasCustomerReachedMaxOrderAmount的形式)添加到启动Saga的事件中。

我选择的第二个选项是准备一个与Sagas一起使用的读模型,并从那里查询数据,但是我甚至会在saga启动之前收集所有必需的信息。这种丰富可以由AR引发的原始事件的处理程序执行,因为这不是聚合/有界上下文的一部分。

在大多数情况下,基于通过事件传递的数据是足够的,因为Sagas应该仅以进程的形式包含业务逻辑。这通常意味着你最终可能会有一个Saga(跟随你的例子OrderSagaOrderWithMaxAmountSaga)。

所有这一切,考虑到您提供的示例场景,我认为决定订单是否需要授权应该是您的域本身的一部分,并在启动saga时通过。

我会像这样建模这种情况 - CustomerAR计算最大金额;客户下订单 - > {em> 创建了 此客户的最大金额信息,OrderAR验证是否需要其他授权 - > Order开始吧。关键是有关最大金额的信息对于Saga(可以改变的地方)和CustomerAR(它是不可变的)都很重要。

答案 1 :(得分:0)

我刚刚开始涉足DDD,我不打算重复kstaurch所说的任何事情,但这里有一些想法,我看过你的情景:

  1. 如何将最大订单金额作为结算信息的一部分?这必须得到某个地方,我相信你会处理拒绝付款处理的情况。

  2. 如果saga 总是发送授权命令怎么办,但它是处理最大订单屏幕的授权部分?如果您说“如果金额超过$ X然后获得授权”,也许您的商业模式也会将其视为“如果它低于$ X,则自动批准”。好处是所有审批注意事项(包括是否获得批准)可以移至审批实体或传奇。