使用事件采购在DDD / CQRS中同时捕获大量聚合的创建

时间:2014-09-25 15:06:39

标签: architecture domain-driven-design cqrs event-sourcing

我有一个使用文件的聚合,并因此创建了大量其他聚合。

e.g。
工厂总计(事件来源)
产品聚合(事件来源)

List<Product> Factory.CreateProducts(specifications);

CreateProducts的调用会产生一个事件:FactoryCreatedProducts,一旦我保存了工厂聚合,就会将其保存到事件流中。该调用还会产生10000 + Product个聚合,在实例化时,每个聚合将包含一个ProductCreated事件,该事件将保存到事件流中。

目前,我的编码如下:

var factory eventstream.get(command.FactoryId);
var products = factory.CreateProducts(command.specs);

foreach(var product in products) {eventstream.save(product.PendingEvents);}

eventstream.save(factory.PendingEvents);

对我而言,这种方法存在一些基本问题,其中最大的问题是:

  1. 一次修改多个聚合。
  2. 通过消息总线携带10000多条消息并在读取模型生成器中独立处理它们的开销。
  3. 作为替代方案,我可能会将整个事件作为消息总线中的一个事件推送,但这将意味着一个潜在的巨大事件随着生成的聚合数量的增长而变大。

    我对此问题的解决方法是否常见,还是我完全错过了这个问题? 什么是在DDD / CQRS架构中处理事物的正确方法,其中事件源用于聚合的持久性?

    P.S。与问题无关但我使用C#,MongoDb用于持久性,Windows Service Bus但是切换到RabbitMQ。

1 个答案:

答案 0 :(得分:0)

从技术上讲,你正在做的事情很适合佐贺的想法;但即使作为一个传奇,你也会产生10k +事件来创造10k +产品。您是否在第一次发送命令时考虑过懒惰地创建产品?

var product = aggregateRepository.find(productId);
if (!product) {
   var productSpecs = db.fetchProductSpecs(productId);
   product = factory.CreateProduct(command.specs);
}
product.someHandler(...

或者在后台更慢地创建产品,这样就不会使读模型更新器饱和。

假设您对产品的建模是正确的,那么您确实希望每个产品有1个事件来宣布它的创建。