【问题标题】:Should latest event version be queried in event sourcing?事件溯源中是否应该查询最新的事件版本?
【发布时间】:2018-04-11 16:54:52
【问题描述】:

我正在为教育目的开发一个简单的基于 DDD + 事件溯源的应用程序。

为了在存储到事件存储之前设置事件版本,我应该查询事件存储,但我的直觉告诉这是错误的,因为它会导致并发问题。

我错过了什么吗?

【问题讨论】:

  • 它不会导致并发问题如果您在事件存储中有一个约束(即aggregateType-aggregateId-version 上的唯一约束)
  • 不确定在事件存储中存储聚合类型是否是个好主意,列是:'aggregateId, version, eventData'
  • 这取决于您的设计。在矿山设计中,不同的聚合类型可以共享相同的ID值。
  • @SHM 我写的是“聚合类型”而不是“事件类型”
  • @SHM 如果您使用的是 eventstore.org,那么您是安全的;这些人保护您的事件流免受并发问题的影响;你可以在这里阅读更多:eventstore.org/docs/dotnet-api/…

标签: domain-driven-design cqrs event-sourcing event-stream eventstoredb


【解决方案1】:

对此有不同的答案,具体取决于您考虑的用例。

通常,事件存储是一个愚蠢的、与域无关的设备。它表面上类似于List 抽象——它存储你放入其中的内容,但它实际上并没有做任何工作来满足你的域约束。

在您的事件流只是已发生事件的持久记录的用例中(意味着:您的域模型没有被否决;记录事件不依赖于先前记录的事件),那么附加语义就可以了,并且根据您使用的设备类型,您可能不需要知道要写入流中的哪个位置。

例如:GetEventStore 的 API 将 ExpectedVersion.ANY 理解为将这些事件附加到流的末尾,无论它发生在哪里。

如果您确实关心以前的事件(域模型应确保基于其先前状态的不变量),那么您需要做某事以确保您正在附加事件到您检查过的相同历史记录。最常见的实现会传达写入光标在流中的预期位置,以便设备可以拒绝写入错误位置的尝试(这可以保护您免受并发修改)。

这并不一定意味着您需要查询事件存储来获取位置。您可以在加载流时计算流中的事件数量,并记住您添加了多少事件,因此如果您仍然与流同步,流“应该”在哪里。

我们在这里所做的类似于比较和交换操作:我们得到流的原始状态的表示,创建一个新的表示,然后比较和交换对原始状态的引用,而不是指向我们的变化

oldState = stream.get()
newState = domainLogic(oldState)
stream.compareAndSwap(oldState, newState)

但由于流是一种仅具有附加语义的持久数据结构,因此我们可以使用不需要复制现有状态的简化 API。

events = stream.get()
changes = domainLogic(events)
stream.appendAt(count(events), changes)

如果您的设备的 API 不允许您指定写入位置,那么可以 - 当其他写入器在您对位置的查询和您尝试写入之间更改流的位置时,存在数据竞争的危险写。查询中获得的数据总是陈旧的;除非您持有锁,否则您无法确定在读取本地副本时数据在源头没有更改。

【讨论】:

    【解决方案2】:

    我猜你不应该考虑事件版本。

    如果您谈论事件流中的位置,一般来说,没有保证在创建时刻确定它的方法,只能在处理时间或事件存储中确定。

    如果它与事件版本完全相关(请参阅http://cqrs.nu/Faq,我如何对事件进行版本/升级?),您已将其硬编码在您的应用程序中。所以,我的意思是下一个用例:

    首先,您有一个应用程序会生成一些事件。接下来,您更新应用程序并更改事件(添加一些字段或更改有效负载结构)但保持逻辑含义。因此,现在您的 ES 中有旧事件和新事件,它们与旧事件有很大不同。并且为了区分你使用事件版本,例如 0 和 1。

    【讨论】:

    • 我认为您在谈论版本控制模型......而不是序列本身的版本。我认为操作员正在询问测序。我遇到了类似的问题。我的缓存检查 ES 中的最新版本。如果不一样,我转储缓存,然后重新加载聚合并将其存储在缓存中。
    猜你喜欢
    • 2023-03-14
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2023-03-10
    • 2017-04-06
    • 2020-05-27
    相关资源
    最近更新 更多