首页 文章

CQRS:更新没有事件采购的读取模型

提问于
浏览
5

我们使用域侧的关系数据库和读取端的NoSQL DB构建了基于CQRS的系统 . 域侧遵循经典的关系方法,而读取侧是非规范化的 . 使用命令处理程序发出的事件完成数据复制和转换 .

我有两个关于读取端同步的问题:

  • 使用域侧的关系数据完全重建读取模型的最佳方法是什么?

我们假设读模型不同步 . 但即使它始终保持同步,也可能需要导入测试数据库或进行一些批量操作 . 因此,人们可能希望从现有的写模型运行系统,而不需要相应的同步读模型 . 由于我们不使用Event Sourcing,因此无法重播所有事件 .

我目前认为 ReadModelBuilder 基本上在每个表上执行SELECT * FROM并将每个实体转换为读取端表示 . 但这引入了冗余 . ReadModelBuilder需要知道转换是如何完成的 . 事件处理程序也是如此,它通常在命令处理程序执行某些写操作后执行读取端同步 .

我考虑丢弃事件处理程序,并在每个类级别上用同步机制替换它们 . 例如 . 而不是 FooRenamedEventHandler 重命名 foo.name ,它将调用 FooReadModelBuilder ,它重写完整的 Foo 实例 . 但我认为这有弊端 . FooRenamedEventHandler可以更好地处理读取模型中 foo.name 的冗余使用 .

UPDATE: 另一种方法可能是让 ReadModelBuilder 通过将域实例分段为事件来创建读模型实体,这将在顺序执行时构建完整的读取端实体 . 例如:

Article 域实体具有 NamePrice . 要构建读取端模型, ReadModelBuilder 可以检查域实体并发出 ArticleCreatedEventArticleRenamedEventArticlePriceChangedEvent . 这样,转换逻辑将保留在事件处理程序中,但仍可从某种批量复制机制中调用 .

例如,ReadModelBuilders可能如下所示:

_

interface IReadModelBuilder<TEntity>
{
    //// Returns a sequence of events which replicate the read-model 
    //// when executed by the event handlers.
    Event[] GetReplicationSequence(TEntity instance);
}

END OF UPDATE

_

  • 您如何检测不同步的读取模型?是否有一般的最佳做法?

先感谢您 .

1 回答

  • 1

    如果您没有保留事件(即不使用 Event sourcing ),则无法轻松重建 read-model . 你的 Rebuilder 必须以某种方式尝试对写模型进行反向工程并制作一些奇怪的事件,因为 write model 甚至不能包含所有信息,因为它不需要它来完成他的工作 .

    所以,我的结论是,如果没有 event store 或至少 event log 那么你就无法重建你的 read-model . 如果您有这样的事实来源,那么您可以重建它,甚至通过在某些持久性中使用所有已处理事件ID的列表来检测不同步情况 .

相关问题