gpt4 book ai didi

cqrs - 重播事件的 NEventStore 问题

转载 作者:行者123 更新时间:2023-12-04 15:23:42 25 4
gpt4 key购买 nike

我们正在使用 CQRS + ES。 ES 是 NEventStore(以前称为 JOliver EventStore)。我们在不同的命令中有 2 个聚合。第二个 AR 的投影取决于读取模型中第一个 AR 投影写入的数据。问题在于,当我们运行软件时,一切都进行得如此之快,以至于有时两个聚合会以相同的日期时间(CommitStamp 列)持久存在于事件存储中。当重放事件时,我们从 CommitStamp 列的开始顺序获取它们。但是,如果两个流具有相同的 CommitStamp 并且以错误的顺序获取,则读取模型预测会出现异常。

知道如何解决这个问题吗?

================================

这是github上关于这个问题的讨论
https://github.com/NEventStore/NEventStore/issues/170

================================

编辑 :这就是我们目前重播事件的方式。我搜索了 GetFrom(...) 的工作原理,结果发现 commitstamp 列不用于排序。毕竟没有提交顺序。因此,如果我开始重播事件,它可能会返回今天的事件,下一个 2 年前记录的事件,下一个等

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());
}

最佳答案

在 NEventStore 中,一致性边界是流。从 3.2 版开始(如@Marijn 提到的, issue #159 ),当从所有持久性引擎的流中读取时,CommitSequence 列用于对 CommitMessages(以及其中包含的 EventMessages)进行排序。

EventMessage 排序在 上得到保证每流基础 .跨流的消息没有隐含的排序。由于所选持久性引擎的某些方面而可能发生的任何实际排序都是偶然的,不得依赖。

保证跨流排序将严重限制库的分布式友好方面。即使我们要考虑这样的功能,它也必须与所有支持的持久性引擎一起工作,其中包括 NoSQL 存储。

如果您正在实践领域驱动设计,其中每个流代表一个聚合根,并且您需要保证跨 2 个或更多聚合的排序,这表明您的领域模型中存在设计问题。

如果您的预测需要合并来自多个源(流)的值,您可以依赖于源内排序,但您需要灵活地对源间排序。您还应该考虑重复消息的可能性,尤其是当您通过外部总线或队列重播时。

如果您尝试使用时间戳 (CommitStamp) 在接收器端重新排序多个流,那将是脆弱的。时间戳具有固定的分辨率(毫秒、滴答等)。即使只有一个作家,事情仍然可能“同时”发生。

关于cqrs - 重播事件的 NEventStore 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17483273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com