我们使用的是CQRS + ES。ES为NEventStore (folrmerly JOliver EventStore)。我们在不同的命令中有两个聚合。第二个AR的投影取决于读取模型中第一个AR投影所编写的数据。问题是,当我们运行软件时,一切都进展得如此之快,以至于有时这两个聚合以相同的日期时间(列CommitStamp)持久化在事件存储中。当重播事件时,我们从CommitStamp列排序的一开始就得到它们。但是,如果这两个流具有相同的CommitStamp,并且取错了顺序,那么读取模型的预测就会有例外。
知道怎么解决这个问题吗?
===============================
以下是github https://github.com/NEventStore/NEventStore/issues/170对这个问题的讨论
===============================
编辑:这是我们当前重播事件的方式。我搜索了GetFrom(.)工作,结果是提交邮票列不用于排序。毕竟没有提交命令。因此,如果我开始重播事件,它可能会从今天返回一个事件,然后返回一个2年前录制的事件,next,等等。
public void ReplayEvents(Action<List<UncommittedEvent>> whatToDoWithEvents, DateTime loadEventsAfterDate)
{
var eventPortion = store.Advanced.GetFrom(loadEventsAfterDate);
var uncommitedEventStream = new UncommittedEventStream();
foreach (var commit in eventPortion)
{
foreach (var eventMessage in commit.Events.ToList()))
{
uncommitedEventStream.Append(new UncommittedEvent(eventMessage.Body));
}
}
whatToDoWithEvents(uncommitedEventStream.ToList());
}发布于 2013-11-13 23:06:45
Damian在数据库中添加了一个检查点列。这是在当前的主分支中。当事件与GetFromCheckpoint(int)重播时,结果是正确的。
发布于 2013-07-08 13:07:59
在NEventStore中,一致性边界是流。在版本3.2 (正如@Marijn提到的,第159期)中,CommitSequence列用于在所有持久性引擎中读取流时排序CommitMessages (以及其中包含的EventMessages)。
EventMessage排序保证基于每个流的(基于)。没有隐含的跨流消息排序。任何可能发生的实际排序都是偶然的,因此所选持久性引擎的某些方面是偶然的,不能依赖。
为了保证跨流的排序,将严重限制库的分布式友好方面。即使我们考虑这样一个特性,它也必须与所有受支持的持久性引擎(包括NoSQL存储)一起工作。
如果您正在实践领域驱动设计(其中每个流代表一个聚合根),并且需要保证跨2个或多个聚合体进行排序,这将指向域模型中的设计问题。
如果您的投影需要合并来自多个源(流)的值,则可以依赖于排序内部源,但您需要灵活地在源间排序。您还应该考虑重复消息的可能性,特别是当您通过外部总线或队列重播时。
如果您试图使用时间戳(CommitStamp)重新排序接收端的多个流,这将是脆弱的。时间戳具有固定的分辨率(毫秒、滴答等)。即使只有一位作家,事情也可能“同时发生”。
发布于 2013-07-05 12:07:16
在数据库级别,虽然CommitStamp可以进行筛选,但CommitSequence列应该指导排序。
至于这一点,在API调用方面,您正在使用的任何版本的库--我将把它作为练习留给您(或者如果您填写代码片段和/或提及版本,也许其他人可以介入)。
https://stackoverflow.com/questions/17483273
复制相似问题