4

您将如何解决 CQRS 架构中的以下问题:

  1. 有一个名为 Order 的域实体。
  2. 需要处理订单。
  3. 新创建的订单未处理并在处理队列中
  4. 每个订单不得多次处理。
  5. 有多个 Windows 服务可以查询(读取事物的一面)以获取未处理的订单。

现在,我如何确保每个订单仅由一项服务处理?

我会让服务发出一个 Command StartOrderProcessing(order)。如果由于版本不同,另一个服务已经开始处理此订单,则此命令将在域中失败。
但是,由于命令本质上是异步的,服务如何知道失败?

服务是否应该轮询读取模型以查看订单是否将其状态更改为正在处理?但是,由于它自己的命令而不是因为另一个服务的命令而改变了状态,该服务将如何改变状态?


UL:

  • 订单:我系统中的订单代表用户请求更新他/她邮箱上的问候语。
  • 信箱:当您拨打手机且未接听电话时,您将被重定向到信箱留言
  • 问候语:当您到达邮箱时,您会收到一条短信,告诉您在哔声后留言。此文本(不是您的消息!)是问候语。
  • 激活:在邮箱中设置新问候语的过程称为激活。正在激活问候语。
  • 运营商:提供手机服务的公司,例如 T-Mobile。

处理订单的步骤:

  1. 从预先录制的声音位创建问候语。这取决于邮箱关联的运营商。
  2. 执行运营商特定的工作流程以激活邮箱上的问候语。此工作流程具有以下元素:

    2.1。调用邮箱
    2.2。使用 DTMF 音
    2.3 导航邮箱菜单。识别邮箱发送的某些音频元素(如确认蜂鸣声)
    2.4。播放在 1 中创建的问候语

    该工作流被定义为 Windows Workflow Foundation 工作流,因为每个运营商的工作流都不同。

  3. 成功时:

    3.1。保存激活呼叫的录音
    3.2。通过邮件通知用户成功

  4. 出错时:

    4.1。保存失败的激活呼叫和失败原因的记录
    4.2。如果这是第一次尝试,请安排 Order 在 X 分钟内重试
    4.3。如果这是第二次尝试,请通过邮件通知用户失败

4

2 回答 2

2

首先,您需要整理出队,以便只有一个服务实例可以出队并处理订单。看看这个:http ://www.eaipatterns.com/CompetingConsumers.html

例如,NServiceBus 为您提供了开箱即用的功能。

然后您可能想考虑您的订单处理。StartOrderProcessing对我来说听起来不像是一个商业步骤。处理订单的真正步骤是什么?

订单的处理实际上可能是一个有限状态机。它有一个入口点和一个或多个退出条件。

看一下 saga 概念,其中聚合可以通过状态机并收集可以发送到域或其他有界上下文的信息,以便让他们做出决策,进而推动 saga 向前发展。

看看这个:https ://github.com/haf/Documently/wiki/Sagas-SnowPloughExample

于 2012-08-21T14:41:51.930 回答
1

听起来 和 之间不仅有区别,而且Order有区别。也许这些应该单独建模以反映领域。这不仅可以优化域模型,还可以帮助简化您的问题。UnprocessedOrderProcessedOrder

于 2012-08-21T19:05:15.090 回答