Design patterns 为什么不应该';存储库不能保存事务逻辑吗?

Design patterns 为什么不应该';存储库不能保存事务逻辑吗?,design-patterns,architecture,transactions,domain-driven-design,Design Patterns,Architecture,Transactions,Domain Driven Design,拥有一个设计良好的域,具有互不引用的聚合、定义良好的边界和具有定义良好的对象引用的聚合对象,为什么在存储库中拥有事务逻辑(为每个域对象创建存储库)是一种不好的做法 在使用UoW模式回答之前,请考虑此问题 因为一个典型的事务通常跨越多个存储库。当你在同一笔交易中将你想要的产品出售给 减少库存中的元素数量(库存存储库) 创建订单(OrderRepository) 创建装运(ShipmentRepository) 您真的希望所有这些要么成功,要么失败。即使在每个事务一个聚合的情况下,代码块通常如下

拥有一个设计良好的域,具有互不引用的聚合、定义良好的边界和具有定义良好的对象引用的聚合对象,为什么在存储库中拥有事务逻辑(为每个域对象创建存储库)是一种不好的做法


在使用UoW模式回答之前,请考虑此问题

因为一个典型的事务通常跨越多个存储库。当你在同一笔交易中将你想要的产品出售给

  • 减少库存中的元素数量(库存存储库)
  • 创建订单(OrderRepository)
  • 创建装运(ShipmentRepository)

您真的希望所有这些要么成功,要么失败。

即使在每个事务一个聚合的情况下,代码块通常如下所示:

 Order order = orderRepository.findBy(orderId);(1)
 order.doSomething();
 orderRepository.store(order);//or omitted with uow

从技术上讲,当某些步骤不在存储库中时,如何在存储库中实现事务逻辑和锁定策略?

,因为它打破了单一责任原则。存储库是聚合根集合的提供者,而不是事务协调器。此外,它们的实现位于持久性层,这意味着它们的视野太低,甚至无法意识到诸如业务事务之类的重大问题。

存储库不能引用域中的对象之类的其他存储库吗?那么事务可以驻留在这个层中?如果没有,事务逻辑应该驻留在哪里?UoW限制我进行简单交易,如链接问题中的交易。我是否应该仅仅为了这些事务的目的而创建服务层?为了事务的目的,为了实现您的业务逻辑。当您销售10种产品时,您希望创建一个包含10个订单行的单订单,并根据产品的重量和体积,根据需要创建尽可能多的发货,并在新库存量低于某个限制等情况下发出警报。这是需要实施的业务逻辑,而且它不属于涉及的三个存储库中的任何一个。存储库的全部要点是将持久性逻辑与业务逻辑解耦。我有点不同意。如果您有一个干净的域模型,并且遵循“每个事务一个聚合根”原则,即通过将跨越多个聚合的所有业务逻辑移动到一个长期运行的流程/saga中,我看不出您的存储库不应该处理事务逻辑的任何原因。恰恰相反,事务逻辑是一个与数据库概念密切相关的基础架构问题,而其他存储方法(如文件系统)则没有事务概念。@JBNizet您永远不会有OrderLineRepository,因为OrderLine是订单的一个细节,所以您只有OrderRepository。Alexander Langer有一点,对于跨多个域/服务器的事务,saga是实现它的最干净的方法,存储库不应该知道它。如果一个域存储库将东西存储在云中或文件系统上会怎么样?ACID适用于某些db引擎,它是一种特殊情况的解决方案,而不是通用的解决方案。而高效查询目前主要是nosql领域。RDBMS仍然有一个角色,但它不再有单极子。如果一些逻辑需要调用多个存储库,那么这个逻辑应该在一个服务中。我不明白为什么用他们的产品检索订单需要的不仅仅是一个查询。如果需要,那么我将创建一个服务,该服务将调用订单存储库中的适当方法,以及产品存储库中的适当方法。否则,您将很快得到大量依赖项,您还将在产品存储库中获得对订单存储库的引用,从而产生循环依赖项。:)如何持久化您的对象?实际上,它们还需要数据库层的一致性,例如。你的视野不是很低,你需要在数据库中映射状态,这样你就可以检索一致的对象。我特别提到了数据库事务(也需要常量)。出于一致性的原因,您甚至可以在数据库端为复杂的设计/逻辑创建触发器(我不得不这样做是为了db多态关联)。这个例子只是为了说明数据库也需要与域相关的一致性。我不通过存储库持久化我的对象。我从存储库公开的集合中添加或删除对象,或对其进行修改,但这些更改不会立即持久化。应用层服务知道正在进行的用例的状态,可以决定何时持久化。如何持久化也不是由存储库实现的,而是通常由ORM实现的。即使没有ORM,我也会有一个特定的适配器对象,它可以从逻辑/业务提交转换为物理提交(可以是DB事务提交或其他)。分开的责任,分开的对象。我认为你把工厂和仓库搞混了。存储库是从存储技术中抽象模型的层。即使您使用ORM,也应该从存储库中调用映射器(谁知道以后您可能会切换到非关系数据库)。工厂与此无关。我没有说存储库不应该调用ORM,只是说它不应该知道如何持久化(=最终提交到持久化存储)。这里有一个例子说明了我的意思:你能举一个例子说明“在存储库中拥有事务逻辑”是什么意思吗?存储库中的给定方法是否包含整个业务事务,您是否会调用存储库中的单独方法来启动和提交事务?