9

当我有点困惑在使用域中的事件来构建模型读取系统中的流动。特别是,我们如何处理用户期望数据(及其视图)在完成命令时发生更改的事实,但是由于我们的系统体系结构(非阻塞调用发布事件),实际数据库可能不会在页面重新加载?在查看显示的变化使用CQRS和DDD与域事件与ServiceBus

我希望用活动和服务总线CQRS更内嵌移动我们的一个系统的设计。

比方说,我的流转这样:

  1. 用户点击查看按钮执行从他们的帐户删除付款方式的任务。

  2. 控制器调用PaymentMethodRemovalService并将其传递给accountId & paymentMethodId。

  3. 控制器采用AccountRepository检索帐户,并呼吁account.RemovePaymentMethod(ID)

  4. 帐户验证可能出现的操作和发布事件PaymentMethodRemovedMessage(帐户,paymentMethodId)

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

  6. 处理程序,IHandle < PaymentMethodRemovedMessage>,听到该事件,并从DB

所以消除了实际行,什么是一个人做的?

我可以简单地说,删除显示付款方式的div。这可能适用于AJAX场景,但如果我使用Post-Redirect-Get来支持非JavaScript客户端,该怎么办?然后,我会在我更新之前触发我的Get并从事物的Query侧读取数据。

难道我只是显示一个通知说,他们的要求删除付款方式已提交? (这似乎不友好,对于提交订单是有意义的,但不适用于改变地址)。

有没有办法调和实现变化解耦异步事件和展示反映其电流变化的用户数据?

编辑:我的问题是非常相似CQRS, DDD synching reporting database我不得不说,考虑到那里,也提到了这里的答案,有一点异味,以它的 - 争论的UI显示的更新这是带外与可以这么说,读数据库。我希望有更清洁的东西。

回答

8

如果你陷入了请求/响应模型,你可以采取相关请求/响应模式。有关详细信息,请查看NSB下载中的异步页面示例。这演示了ASP.NET设置中的请求/响应。有一些ASP.NET MVC的例子,如果这是更多的东西。

当你介绍异步处理您接受该数据将会过时。人们可以争辩说,当你查询数据库时,数据已经老化(网络延迟,渲染时间等)。由于数据已经很老了,我们必须问问多大年纪了?

还有一件需要考虑的事情是您的处理有点不合理。步骤3应在将命令发送到服务器之前进行验证,然后步骤3,4将在6之后进行。数据库只应在命令有效时更新,并且只有在数据库成功更新后才会发布该事件。

0

此问题被称为“最终一致性”。有明确的方法来处理它。第一点是每个系统都有最终的一致性,无论他们是否使用异步事件。只是你选择了明确,而大多数其他系统只是让用户等到更新完成。只要明确选择,两种方法都是有效的。

后来我写了一篇关于这个主题的博客文章,您可能会发现有帮助。你可以在这里找到它:4 Ways to Handle Eventual Consistency on the UI

这里是一个简短的版本:

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

选项2 - 假的。如果用户尝试的操作很有可能成功,那么伪造它可能是一种合理的方法。购买高需求票时通常使用这种方式。您的交易可能会经过,但稍后公司发现您的票已经在毫秒之前售出。对公司的好处是他们有销售而不是失去两个客户的风险。只要系统是小心建立的,这种情况应该很少发生,因此整体上不成问题。

您还可以使用关联标识来允许您订阅操作的成功或失败。

无论如何,希望提供一些思考。