我们已经构建了一个基于CQRS的系统,在域端使用关系数据库,在读取端使用NoSQL数据库。域端遵循一种经典的关系方法,而读取端则是非规范化的.数据复制和转换是使用命令处理程序发出的事件完成的。
关于读取端同步,我有两个问题:
ReadModelBuilder,它基本上对每个表执行SELECT * FROM,并将每个实体转换为读取端表示。但这会带来冗余。ReadModelBuilder需要知道转换是如何完成的。事件处理程序也是如此,这些处理程序通常在Command执行一些写操作之后进行读端同步。
我考虑放弃事件处理程序,并在每个类级别上用同步机制替换它们。例如,它将调用重写完整的FooRenamedEventHandler实例的FooReadModelBuilder,而不是重新命名foo.name。但我觉得这有缺点。FooRenamedEventHandler可以更好地处理读取模型中foo.name的冗余用法。
UPDATE:另一种方法可能是让ReadModelBuilder通过将域实例分割为事件来创建读模型实体,这将在顺序执行时构建完整的读取端实体。例如:
Article域实体有一个Name和一个Price。为了建立读取端模型,ReadModelBuilder可以检查域实体并发出ArticleCreatedEvent、ArticleRenamedEvent和ArticlePriceChangedEvent.这样,转换逻辑将保留在事件处理程序中,但仍然可以从某种批量复制机制中调用。
例如,ReadModelBuilders可能如下所示:_
interface IReadModelBuilder<TEntity>
{
//// Returns a sequence of events which replicate the read-model
//// when executed by the event handlers.
Event[] GetReplicationSequence(TEntity instance);
}更新的端
_
发布于 2017-08-31 07:45:43
如果您不持久化事件(即不使用Event sourcing),那么您就无法轻松地重新构建read-model。您的Rebuilder必须设法反向工程编写模型,并捏造一些事件,这是奇怪的,因为write model甚至不能包含所有的信息,因为它不需要它来完成他的工作。
因此,我的结论是,如果没有event store,或者至少没有event log,您就无法重建read-model。如果您有一些像这样的真相来源,那么您可以重新构建它,甚至可以通过在某些持久性中使用所有已处理事件in的列表来检测不同步的情况。
https://stackoverflow.com/questions/45960977
复制相似问题