CQRS-何时发送确认消息? [英] CQRS - When to send confirmation message?

查看:82
本文介绍了CQRS-何时发送确认消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


示例:业务规则规定,下订单后,客户应收到确认消息(电子邮件或类似内容)。

Example: Business rules states that the customer should get a confirmation message (email or similar) when an order has been placed.

让我们说, NewOrderRegisteredEvent 是从域中分派的,并由发送确认消息。完成此操作后,其他事件处理程序将引发异常,或者其他错误将导致工作单元回滚。现在,我们已向用户发送确认消息,说明已回滚的内容。

Lets say that a NewOrderRegisteredEvent is dispatched from the domain and is picked up by an event listener that sends of the confirmation message. When that is done some other event handler throws an exception or something else goes wrong and the unit of work is rolled back. We've now sent the user a confirmation message for something that was rolled back.

解决这样的问题的 cqrs方法是什么,在这种情况下,您想要在完成某个工作单元后要做一些事情?另一个复杂的因素是事件的重播。我不希望每当重播录制的事件以建立新的视图/投影时都重新发送旧的确认消息。

What is the "cqrs" way of solving problems like this where you want to do something after a unit of work has been committed? Another complicating factor is replaying of events. I don't want old confirmation messages to be re-sent whenever I replay recorded events in order to build a new view / projection.

到目前为止,我最好的理论是:我才刚刚开始研究迷人的cqrs世界,并且想知道这是否可以实现为佐贺如果一个传奇就像一个状态机,每个转换只能发生一次,那么我想这会解决这个问题吗?我只是很难想象它将如何与命令总线和域事件一起使用。.

推荐答案


  1. 仅在事务完成后才发生事件。如果发生任何错误并且发生回滚,那么从外部角度来看,该事件就没有发生。因此,它根本不应该发布。尽管可以在必要时发布 OrderRegistrationFailed 事件。

您不希望邮件被发送除非命令已成功执行,否则发送。

You wouldn't want the mail to be sent unless the command has sucessfully been executed.

首先,为什么命令处理程序(在另一个答案中提出)会在错误的地方:在某些情况下,命令处理程序将无法告诉命令是否最终成功。让命令处理程序调用邮件发送还会将过程知识放入命令处理程序中,这将破坏SRM,并使业务规则与应用程序层紧密耦合。

First a few reasons why the command handler -- as proposed in another answer -- would be the wrong place: Under some circumstances the command handler wouldn't be able to tell if the command will eventually succeed or not. Having the command handler invoke the mail sending would also put process knowledge inside the command handler, which would break the SRM and too tightly couple business rules with the application layer.

邮件应在事后发送,即从事件处理程序发送。

The mail should be sent after the fact, i.e. from an event handler.

要防止在重播期间触发该处理程序,您不能注册它。这与您测试应用程序的方式相似。您只需注册您实际需要的处理程序。

To prevent this handler from firing during replay, you can just not register it. This works similar to how you test your application. You only register the handlers that you actually need.


  • 生产系统->注册所有事件处理程序

  • 测试->仅注册经过测试的事件处理程序

  • 重放->仅注册投影/非规范化处理程序

另一个-耦合更松散,虽然更复杂-可能是 Saga 句柄 NewOrderRegisteredEvent 并向适当的有界上下文发出 SendMail 命令(感谢Yves Reynhout,请在问题的评论)。

Another - even more loosely coupled, though a bit more complex - possibility would be to have a Saga handle the NewOrderRegisteredEvent and issue a SendMail command to the appropriate bounded context (thanks, Yves Reynhout, for pointing this out in the question's comments).

这篇关于CQRS-何时发送确认消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆