1

澄清:这个问题是关于 Greg Young 的 Event Store。

我试图软删除包含 2 个事件的流:

var slice = con.ReadStreamEventsBackwardAsync(streamName, 0, 1, resolveLinkTos: true).Result;
es.DeleteStreamAsync(streamName, slice.LastEventNumber, hardDelete: false).Wait();

这个电话是成功的,调查商店发现了一个新的元数据事件。此事件的类型$metadata和包含:

{
  "$tb": 9223372036854775807
}

$tb代表“之前截断”,在删除流和事件中进行了描述。文档说:

删除流时,其 TruncateBefore 或 $tb 设置为流当前最后一个事件编号。

哪个(如您在上面的 json 中所见)并非如此。截断之前设置为long.MaxVaue。尽管这似乎是不好的行为,但它并不是真正的问题。问题是我不能再写入流了。调用以下片段成功完成,但不会将任何事件附加到流中:

await es.AppendToStreamAsync(persistenceId, expectedVersion < 0 ? ExpectedVersion.NoStream : expectedVersion, events);

在上面的片段中,expectedVersion设置为-1. 软删除流的元数据说:

Stream is deleted: False
Meta Stream version: 0
Truncate before: 9223372036854775807
Max count:
Max age:

从流的最后一个事件中读取切片显示:

Last Event number: 1
Next Event number: -1
Status: StreamNotFound

有没有人遇到过同样的问题,并且可能已经找到了允许继续将事件附加到已删除流的解决方案?

4

1 回答 1

3

我通过我的 Pull Request 收到了一些有价值的信息。首先,Event Store 的行为是正确的,即使它在当前时间点的行为不像文档中描述的那样。

我们无法写入流的原因是EventStore 将我们的事件识别为重复事件并忽略它。重复是与先前接收到的事件具有相同 id 的事件。事件 id 是客户端生成的,既不是流名称也不是事件索引。

这意味着您在生成事件 ID 时必须小心。确保您的活动 ID 是唯一的!

我们的问题是我们的事件 id 是Guid从流名称和事件计数确定性地生成的。事件计数是流中的事件数。软删除流包含 0 个事件,导致软删除后第一个事件的 id 与删除流之前的第一个事件具有相同的 id(删除后的第二个事件生成与删除前的第二个事件相同,等等)。

StreamEventSlice.LastEventNumber我们的解决方案是根据(由 ClientApi 公开)而不是根据流中的事件数量来计算事件 id 。

于 2018-10-04T09:09:12.763 回答