【问题标题】:CQRS/Event Sourcing: How to enforce data-integrity?CQRS/事件溯源:如何执行数据完整性?
【发布时间】:2014-05-04 12:00:42
【问题描述】:

如果我实现 CQRS 和 Event Sourcing,假设数据的最终存储(读取存储)在 RDBMS 中,我如何维护数据的完整性和一致性?

如果发布了一个事件,但 RDBMS 拒绝从它派生的数据,因为检查违规或缺少 FK 引用怎么办?

【问题讨论】:

  • 在 CQRS 中,事件源(存储)是您保持完整性的地方。
  • 可以将关系数据库用作事件存储吗?我发现的大多数示例大多使用一些序列化格式来存储事件。

标签: cqrs event-sourcing


【解决方案1】:

CQRS 意味着至少 2 个模型:写入和读取。两者都可以存储在同一个数据库或不同的数据库中。使用 ES ,您正在使用一个事件存储,它本身可以在 rdbms 之上实现(在 .net 中有 NEventStore,afaik 可以与 许多 数据库 rdbms 一起使用)。

您是说您在 rdbms 中有 read 模型,这很好。不需要强制执行,因为它是 read 模型,模型更新程序之外的任何人都不会触及它。应用程序客户端只能查询该模型,不能修改它。这就是为什么您首先有 2 个模型,以便域可以使用“写入”模型,而应用程序的其余部分可以使用“读取”模型。

此外,RDBMS 不应该真正拒绝任何东西。事件处理程序应该是幂等的,因此,假设处理程序插入了具有唯一 id 的内容,则第二次调用应该简单地忽略任何违反唯一约束的行为。使用 CQRS,您使用 RDBMS 约束来支持幂等性,而不是实现某些业务规则。

此外,将读取模型视为“丢弃模型”,可以随时更改或重建。

【讨论】:

    【解决方案2】:

    我们的阅读模型非常简单。我们没有外键,所以这是不可能的。为什么需要外键?您可能有外键值,但您不需要约束,因为这是由您的域模型强制执行的。您实际上只是在阅读,如果需要,您可以重建所有读取存储。

    【讨论】:

    • 我们的数据库被多个应用程序客户端访问,因此需要在数据库层强制执行数据完整性。
    • 真的不明白为什么如果它只是一个读取模型。如果他们正在管理一个领域的各个方面,那么您的领域模型不应该让问题发生。如果两个应用程序正在更新您的域,则域应该处理它。应用程序是否在不同的有界上下文中?您的读取模型应根据其特定用途进行分离。
    猜你喜欢
    • 1970-01-01
    • 2019-01-31
    • 2018-02-17
    • 2018-11-15
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    相关资源
    最近更新 更多