必须仅由一个服务处理的项目

时间:2012-08-21 12:53:01

标签: architecture cqrs

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

  1. 有一个名为Order的域名实体。
  2. 需要处理订单。
  3. 新创建的订单未经处理并处于处理队列中
  4. 不得多次处理每个订单。
  5. 有多个Windows服务可以查询(读取事物的一面)未处理的订单。
  6. 现在,我如何确保每个订单仅由一个服务处理?

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

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


    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。如果这是第一次尝试,请安排在X分钟内重试的订单
      4.3。如果这是第二次尝试,请通过邮件通知用户有关失败的信息

2 个答案:

答案 0 :(得分:2)

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

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

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

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

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

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

答案 1 :(得分:1)

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