您如何解决CQRS架构中的以下问题:
现在,我如何确保每个订单仅由一个服务处理?
我会让服务发出命令StartOrderProcessing(order)
。如果其他服务已经开始处理此订单,则此命令将在域中失败,因为版本不同
但是,由于Command本质上是异步的,服务如何知道失败?
服务是否应该轮询读取模型以查看订单是否将其状态更改为处理?但是现在服务如何因为自己的命令改变状态而不是因为另一个服务的命令?
UL:
处理订单时的步骤:
执行特定于运营商的工作流程以激活邮箱上的问候语。此工作流程包含以下元素:
2.1。呼叫邮箱
2.2。使用DTMF音色导航邮箱菜单
2.3。识别邮箱发送的某些音频元素(如确认蜂鸣声)
2.4。播放1中创建的问候语
工作流程定义为Windows Workflow Foundation工作流程,因为每个运营商都有所不同。
成功:
3.1。保存激活呼叫的记录
3.2。通过邮件通知用户成功
出错:
4.1。保存失败的激活呼叫记录和故障原因
4.2。如果这是第一次尝试,请安排在X分钟内重试的订单
4.3。如果这是第二次尝试,请通过邮件通知用户有关失败的信息
答案 0 :(得分:2)
首先,您需要整理出队列,以便只有一个服务实例可以出列并处理订单。看看这个:http://www.eaipatterns.com/CompetingConsumers.html
例如,NServiceBus为您提供了开箱即用的功能。然后您可能想要考虑订单处理。 StartOrderProcessing 对我来说听起来不是一个商业步骤。处理订单的真正步骤是什么?
订单的处理实际上可能是有限状态机。它有一个入口点和一个或多个退出条件。
看看传奇概念,其中聚合可以通过状态机进行收集并收集可以发送到域或其他有界上下文的信息,以便让他们做出决策,从而推动传奇向前发展。
看看这个:https://github.com/haf/Documently/wiki/Sagas-SnowPloughExample
答案 1 :(得分:1)
听起来不仅仅是Order
,而是UnprocessedOrder
和ProcessedOrder
之间的区别。也许这些应该单独建模以反映域。这不仅可以改进域模型,还可以帮助简化您的问题。