CQRS如何获得聚合最终版本?

时间:2016-05-22 12:41:31

标签: c# cqrs event-sourcing

假设您有一个可能在聚合上生成多个事件的命令。你如何弄清楚最终版本究竟是什么?因此,在知道所有事件都已处理之前,您不会从读取模型中获取它。

ServiceLocator.CommandBus.Send(new SomeCommand(..., currentVersion));

使用命令总线我没有看到获得返回值的明显方法,说明新的聚合版本。

建议?

1 个答案:

答案 0 :(得分:1)

据我所知

  1. 你走在正确的轨道上
  2. 是的,指挥巴士挡路了
  3. 由于命令总线不允许您传回所需的信息,因此您必须将其传递,然后进行查询。命令处理程序在某处写入您想要的信息,并在获得命令已完成的信号后查询它。

    换句话说,您可以将应用程序本身视为一个抽象,您可以在其中发送命令,命令更新版本号,并查询这些版本号。这个抽象被分成了不同的职责 - 命令职责是通过命令总线实现的,而查询职责是......好吧,这就是要解决的问题。

    您的每条命令消息都应该有一个唯一的标识符(无论如何,您将需要像幂等性一样的东西)。成功持久化事件后,命令处理程序将新版本号写入键值存储,使用命令id作为键。

    在您的来电者中,您将阻止该条目可用;然后从商店阅读并继续前进。

    不是我最喜欢的选择,但它并没有真正违反我们所教授的任何良好/成功设计的原则。

    例如,Gregor Hohpe谈到使用correlation identifier来协调请求消息和回复消息。在此示例中,请求将是具有其标识符的Command,并且回复将是描述流的新高水位标记的消息。

    例如,您可能会想象应用程序获取事件源实体的新事件列表,保存它们,然后发布一个新事件,说“流现在是版本12345”。提交命令消息后,您的代码将一直阻塞,直到高水位消息到达为止。

    (如果消息没有在合理的时间内出现?重新发送命令!我们确保命令是幂等的,这样就可以了。)

    另一种可能性:也许你真的不需要知道高水位线;毕竟,你有命令ID。如果命令持久存在的事件具有因果关系标识符(意味着每个事件都使用生成它的命令的id标记),并且您相信事件历史记录是以原子方式保存的,那么...将查询保持独立于命令;当命令完成时,“重定向”到查询,传递命令标识符,并具有查询块,直到历史记录中出现至少一条具有正确命令ID的消息。

    老实说,这与以前的行为相同,只是将阻止放在不同的地方。

    另一种可能性是客户端跟踪版本本身。粗略的想法是,即使记录簿受到服务器的保护,客户端也可以拥有自己的模型副本,以及它关心的对象的缓存。客户端在本地运行命令以确保它不会犯规,然后将命令发送到服务器 - 如果命令成功,已经知道答案是什么。

    将其视为乐观并发的另一种形式。