如何处理跨越有界上下文的长时间运行的进程/ saga用例

时间:2014-10-11 08:26:08

标签: transactions domain-driven-design eventual-consistency

我正在研究这个用例:

  1. 预算已分配给组织单位
  2. Mike使用预算命令
  3. Jane对此订单表示确认,验证它。此操作会触发这些后果:
    1. 检查预算余额,看看我们是否可以接受此订单:包含失败,请通知Jane。
    2. 预算减少到订单金额
    3. 订单状态已从WAITING_VALIDATION更改为VALIDATED
    4. 向Jane
    5. 显示成功消息
  4. 其他用例信息:

    • 对于我们的用户,3.1到3.4的步骤必须是实时的。 Jane单击按钮并等待答案:确定或不正常 AND 订单状态为有效

    我正在考虑:

    • 预算是一个有限的背景。
    • 排序是另一个有界的背景。
    • 验证步骤将改变2个似乎错误的聚合根。并添加耦合。如果我们需要同时更新另一个聚合根(步骤3,就像为商品创建会计折旧条目一样)。
    • 是实时的,我们可以使用XA事务(例如SQL + Messaging),但我想避免它(而且我目前的技术堆栈不允许我使用XA事务)。

    似乎我们可以使用最终的一致性来实现这种用例:   - 订购服务要求预算服务处理processOrder命令(通过消息或REST):此时订购服务正在等待预算服务。   - Budget Service处理命令(在本地事务中)并将OK / NOK发送给调用者   - 预算服务还会发送OrderInBudgetProcessed事件。   - 订购服务实时接收OK / NOK并通知Jane(但订单状态此时未更改)   - 订购服务处理OrderInBudgetProcessed并更新本地交易中的订单状态。

    我认为这可行。但是我有一些问题:

    • 在订单状态未更新期间,Jane无法打印订单以将其发送给供应商。
    • 在订单状态未更新的期间,我们可以想象Mike想要取消订单。状态仍为WAITING,因此允许操作“取消”。我们必须要求BudgetService订单已经处理完毕吗?如果是,那么我们必须使用订单状态询问所有服务。我们可以使用像传奇或协调员这样的东西吗?
    • 付出补偿行动似乎有很多工作......

    有些问题:

    • “订单验证” - 由两个步骤组成 - 主要由预算上下文或订单上下文处理? (在我看来,主要事件是预算减少所以我在考虑预算背景)。对你来说似乎是逻辑?
    • 您如何看待这种用例?太复杂了?
    • 你怎么处理这个?
    • 我错过了同时拥有干净代码(避免更新/同步同一事务中所有对象的服务)和域用户(Mike / Jane)满意的内容。

    请纠正我错在哪里:)

    期待您的回音。

    弗朗索瓦

1 个答案:

答案 0 :(得分:2)

我曾经遇到过类似的情况,这种方法就像这样:

两个有界的背景:库存和订购

当订单需要fullfilling时,订购上下文接受该命令,它将订单从WAIT_FULLFILL更新为FULLFILLING并发出OrderFullfillingRequiredEvent。

库存上下文订阅此事件并进行库存更新,然后它会发出具有订单跟踪ID的InventoryUpdatedEvent。

订购上下文订阅后一个事件并将订单从FULLFILLING更新为FULLFILLED。

如果有人想在此期间取消订单,它将被拒绝,因为现在状态为FULLFILLING,表示订单正在等待某些回复。

相当于您的用例,我认为它会添加一个中间状态WAITING_VALIDATION - > VALIDATING - > VALIDATED。

仍然需要一些补偿,因为InventoryUpdatedEvent可能永远不会到来。最烦人的问题是在ui方面,也许你需要轮询后端以使其看起来像实时。