存储库和批量更新 - 避免数据库往返

时间:2013-08-06 18:13:59

标签: domain-driven-design repository-pattern ddd-repositories

我在批发系统领域工作。交付某些产品时,会触发域NewProductsDeliveredEvent。事件包含一组包含产品代码和数量的ProductDelivery值对象。如下所示:

class NewProductsDeliveredEvent {
  Set<ProductDelivery> productDeliveries;
}

class ProductDelivery { 
  ProductCode productCode;
  Quantity quantity
}

到目前为止一切顺利。现在,当负责库存更新的组件收到此类事件时。它必须使用当前可用产品数量更新产品表。所以我有类似的东西:

class NewProudctsDeliveredHandler {
  ProductRepository productRepo;  

  handle(NewProductDeliveryEvent event) {
    for (ProductDelivery delivery : event.getProductDeliveries()) {
      Product product = productRepo.getByCode(delivery.getProductCode())
      product.updateQuantity(delivery.getQuantity());
    }
  }
}

很容易发现这样的逻辑产生了很多数据库往返,我正在考虑一些解决方案来减轻痛苦。一个想法可能是使用Specification模式并为产品代码构建OR规范。但是,在我的应用程序中,产品代码是一个业务标识符,所以这个解决方案有点闻名(也许我只是夸大其词)。

有没有更好的方法来处理它?任何想法都非常感激。

1 个答案:

答案 0 :(得分:3)

如果您允许稍微离题,但是您确定在您的情况下批量更新是个好主意吗?

如果产品管理库存,则产品是高度竞争的集合。想象一下,也许有数百人在Amazon.com上同时为同一产品下订单,而很少有人会同时修改您的订单。

举个例子:

   Event1:  A-5, B-1
   Event2:  C-1, D-2
   Event3:  A-2, D-3

Event1与Event3冲突,Event2与Event3冲突

您在一次交易中更新的产品越多,如果您的产品畅销,并发失败的可能性就越大。

每次交易迭代一个产品甚至更糟,使事件更难重试。

handle(NewProductDeliveryEvent event) {
    for (ProductDelivery delivery : event.getProductDeliveries()) {
        updateProductTransactionally(); 
        // How to retry the whole event 
        // when the second one failed and the first one committed?
    }
}

将事件拆分为多个子事件,只触发一次产品更新更合适。