Domain driven design 使用CQRS时显示视图中的更改&;DDD与域事件&;服务总线

Domain driven design 使用CQRS时显示视图中的更改&;DDD与域事件&;服务总线,domain-driven-design,nservicebus,cqrs,event-sourcing,domain-events,Domain Driven Design,Nservicebus,Cqrs,Event Sourcing,Domain Events,我对使用域事件构建读取模型的系统中的流程有点困惑。特别是,我们如何处理这样一个事实:用户在完成命令时希望数据(及其视图)发生更改,但由于我们的系统架构(发布事件的非阻塞调用),在重新加载页面之前,实际数据库可能不会更改 我希望通过事件和服务总线,使我们其中一个系统的设计更符合CQR 假设我的流程是这样的: 用户单击视图中的按钮以执行从其帐户中删除付款方式的任务 控制器调用PaymentMethodRemovalService,将accountId和paymentMethodId传递给它 控制器使

我对使用域事件构建读取模型的系统中的流程有点困惑。特别是,我们如何处理这样一个事实:用户在完成命令时希望数据(及其视图)发生更改,但由于我们的系统架构(发布事件的非阻塞调用),在重新加载页面之前,实际数据库可能不会更改

我希望通过事件和服务总线,使我们其中一个系统的设计更符合CQR

假设我的流程是这样的:

  • 用户单击视图中的按钮以执行从其帐户中删除付款方式的任务

  • 控制器调用PaymentMethodRemovalService,将accountId和paymentMethodId传递给它

  • 控制器使用AccountRepository检索帐户并调用Account.RemovePaymentMethod(id)

  • 帐户验证操作是否可以发生并发布事件PaymentMethodRemovedMessage(accountId,paymentMethodId)

  • 由于事件发布是异步的,我们现在必须从服务返回,并从控制器返回视图-,但实际数据尚未更新

  • 处理程序IHandle会听到事件并从数据库中删除实际行

  • 那么,一个男人该怎么做

    我可以简单地说,删除显示付款方式的div。这可能适用于AJAX场景,但如果我使用Post Redirect Get来支持非JavaScript客户机呢。然后,我将启动Get并从事物的查询端读取数据,可能是在数据更新之前

    我是否只是显示一个通知,说明他们已提交删除付款方式的请求?(这似乎不友好,对于提交订单来说是有意义的,但对于(比如)更改地址来说是没有意义的)

    是否有办法协调将更改作为解耦异步事件实施并显示反映其当前更改的用户数据?


    编辑:我的问题与我不得不说的非常相似,这里给出的答案和这里提到的答案都有一点异味——可以说,为了显示一个与read DB无关的更新,在UI上争论不休。我希望有更干净的东西。

    如果您被锁定在请求/响应模型中,您可以采用相关的请求/响应模式。有关详细信息,请查看NSB下载中的Async Pages示例。这演示了ASP.NET设置中的请求/响应。如果你更喜欢ASP.NETMVC,那么这里有一些ASP.NETMVC示例

    当您引入异步处理时,您接受了数据将过时的事实。有人可能会争辩说,当您查询数据库时,数据已经过时(网络延迟、渲染时间等)。既然数据已经很旧了,我们必须问,多旧才足够好


    还有一件事要考虑的是你的处理有点乱了。步骤3应在将命令发送到服务器之前验证该命令,然后步骤3、4将在步骤6之后执行。只有在命令有效时才应更新数据库,只有在数据库成功更新时才应发布事件。

    此问题称为“最终一致性”。有明确的方法来解决这个问题。首先要指出的是,无论是否使用异步事件,每个系统都具有最终的一致性。只是您选择了显式更新,而大多数其他系统只是让用户等待更新完成。只要明确选择这两种方法,它们都是有效的

    不久前,我写了一篇关于这个主题的博客文章,你可能会觉得很有帮助。你可以在这里找到它:

    以下是一个简短的版本:

    选项1-使用确认屏幕。如果你在手机上使用银行应用程序,你可能已经看到了这一点。在转账过程结束时,您将被带到确认屏幕,然后被带回您的帐户。这使系统有时间恢复到最新状态

    选项2——假装。如果用户尝试的操作很有可能成功,那么假装它是一种合法的方法。这通常用于购买需求量大的车票。您的交易可能会通过,但后来公司发现您的机票在几毫秒前就已经售出。这家公司的好处是,他们有了销售机会,而不是冒着失去两个客户的风险。只要仔细构建系统,这种情况就很少发生,因此总体上不会成为问题

    您还可以使用相关id来订阅操作的成功或失败

    无论如何,希望这能提供一些思考的食物