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

时间:2017-08-30 12:52:06

标签: c# database-design cqrs nosql

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

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

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

    假设读取模型不同步。 但即使它始终保持同步,也可能需要导入测试数据库 或做一些批量操作。所以有人可能想要 从现有的写模型运行系统,而没有相应的同步读模型。由于我们不使用事件采购,因此没有 重播所有活动的方式。

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

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

    更新 另一种方法可以是让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 个答案:

答案 0 :(得分:1)

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

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