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

Transactions 如何处理跨越有界上下文的长时间运行的流程/saga用例,transactions,domain-driven-design,eventual-consistency,Transactions,Domain Driven Design,Eventual Consistency,我目前正在处理这个用例: 预算分配给组织单位 迈克用预算订了一份好的工作 Jane对此订单表示同意,请验证它。这一行动引发了以下后果: 检查预算余额,看看我们是否可以接受此订单:如果失败,通知Jane 预算减少到订单金额 订单状态从等待验证更改为已验证 将向Jane显示一条成功消息 其他用例信息: 对于我们的用户来说,从3.1到3.4的步骤必须是实时的。Jane单击按钮并等待回答:OK或NOT OK和订单状态已验证 我在想: 预算是一个有限的环境 排序是另一个有界上下文 验证步骤将更改2

我目前正在处理这个用例:

  • 预算分配给组织单位
  • 迈克用预算订了一份好的工作
  • Jane对此订单表示同意,请验证它。这一行动引发了以下后果:
  • 检查预算余额,看看我们是否可以接受此订单:如果失败,通知Jane
  • 预算减少到订单金额
  • 订单状态从等待验证更改为已验证
  • 将向Jane显示一条成功消息
  • 其他用例信息:

    • 对于我们的用户来说,从3.1到3.4的步骤必须是实时的。Jane单击按钮并等待回答:OK或NOT OK和订单状态已验证
    我在想:

    • 预算是一个有限的环境
    • 排序是另一个有界上下文
    • 验证步骤将更改2个似乎错误的聚合根。并添加耦合。如果我们需要同时更新另一个聚合根(步骤3,如为货物创建会计折旧条目)
    • 为了实时,我们可以使用XA事务(例如SQL+消息传递),但我希望避免使用它(此外,我当前的技术堆栈不允许我使用XA事务)
    似乎我们可以使用最终一致性来实现这种用例: -订购服务要求预算服务处理processOrder命令(通过消息传递或REST):此时订购服务正在等待预算服务。 -预算服务处理命令(在本地事务中)并向调用者发送OK/NOK -预算服务还发送OrderInBudgetProcessed事件。 -订购服务实时接收OK/NOK并通知Jane(但此时订单状态未更改) -订购服务处理OrderInBudgetProcessed并更新本地事务中的订单状态

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

    • 在订单状态未更新期间,Jane无法打印订单以将其发送给供应商
    • 在订单状态未更新期间,我们可以想象Mike想要取消订单。状态仍在等待,因此允许执行“取消”操作。我们必须向预算服务部门询问订单已经处理了吗?如果是,那么我们必须询问所有使用订单的服务的状态。我们可以用传奇或者协调者之类的东西
    • 提出赔偿诉讼似乎需要做很多工作
    一些问题:

    • “订单验证”由两个步骤组成,主要由预算上下文或订单上下文处理?(在我看来,主要事件是预算缩减,所以我在考虑预算背景)。你觉得合乎逻辑吗
    • 你觉得这种用例怎么样?太复杂了
    • 你是怎么处理的
    • 同时拥有一个干净的代码(避免在同一事务中更新/同步所有对象的服务)和一个域用户(Mike/Jane)满意,我会错过什么呢
    请纠正我的错误:)

    期待您的来信


    弗朗索瓦

    我曾经遇到过类似的情况,结果是:

    两个有界上下文:库存和排序

    当订单需要fullfilling时,排序上下文接受该命令,它将订单从WAIT_fullfilling更新为fullfilling,并发出OrderFullfillingRequiredEvent

    库存上下文订阅此事件并进行库存更新,然后发出一个具有订单跟踪id的InventoryUpdateEvent

    排序上下文订阅后一个事件,并将订单从FULLFILLING更新为FULLFILLING

    如果有人想在此期间取消订单,将被拒绝,因为状态现在为FULLFILLING,表示订单正在等待响应

    与您的用例相同,我认为它将添加一个中间状态等待验证-->验证-->验证


    还需要一些补偿,因为可能InventoryUpdateEvent永远不会出现。最烦人的问题是在ui端,可能您需要轮询后端以使其看起来像实时的。

    +1。面对类似的问题,我将使用事件机制跨有限的上下文触发域活动。谢谢你们。您如何向您的领域专家解释最终的一致性?(我试图解释为什么事件适合我们时失败了),我可以在事件上添加过期时间(以强制在限制上保持一致性)。例如,我的第一个事件有一个2secondes TTL,之后命令处理程序不处理这个事件,并发送一个新事件EVT_TIMEOUT。大天使:第一个问题:我刚刚告诉他们这种方法可以改善整个系统,他们说可以。有时候事情并不是那么简单,但我认为专注于商业价值的提升总是一个好主意。第二个问题:我有一种轮询机制,如果顺序停留在中间状态的时间过长,排序上下文将重新发送事件。要实现这一点,您需要使事件处理程序都是幂等的(可能通过使用事件存储)。我认为你的方法也行得通,唯一关心的是如果EVT_TIMOUT再也不会回来了怎么办。