在阅读Vaughn Vernon的实施领域驱动设计之后,我至少对一件事情感到困惑。 在第12章存储库中,他说事务是在应用程序层中管理的。 但他也说聚合与事务一致性边界同义。 由于存储库提供对聚合的全局访问,因此无法管理事务 在存储库?是因为规则聚合==事务一致性边界只是一个经验法则 有时候必须打破它,或者还有别的东西吗?
答案 0 :(得分:4)
为什么无法在存储库中管理事务?
因为存储库不是"a business transaction"
的抽象,所以存储库是"a collection of domain objects that you can take from or add to"
的抽象。
根据定义,交易有开始和结束。这是一个过程。存储库不是。 Transaction和Repository之间的关系不是是-a ,它的有一个。该事务使用其存储库。
当我们说Aggregate应该是一致性边界时,我们的意思是它应该是事务所包含的状态的唯一块,而不是聚合应该与相同的东西一项交易。
答案 1 :(得分:2)
通常,存储库通过在构造函数中向它们注入一些 Session 或 UnitOfWork 进行实例化,以获取持久存储连接。在一个应用程序服务调用中共享相同的连接是有益的,并且通常这样的调用本身是事务性的,包括读取和写入。我希望,这解释了基本原则。 Vernon给出了@Transactional
服务方法的例子。
此外,在第367页,您可以找到一个名为违反规则的原因的部分,其中他解释了为什么您可以在一次交易中更新多个聚合的理由。
我的最后一点是你应该记住,集合式存储库并不太了解如何将内容提交到存储。他们跟踪更改并向UoW报告,UoW执行提交(或回滚)。
答案 2 :(得分:0)
我怀疑规则肯定会被打破。在一个简单而理想的场景中,聚合可以实现良好的事务一致性边界。但现实世界很少像教科书中的例子那样让我们相信。 (与所写的每本物理教科书相反,在完美的真空中没有无摩擦的表面。如果有的话,肯定不会站在那里。)
通常,我倾向于将事务边界视为围绕业务操作,而不是对象。特定操作可能涉及各种对象。
作为一个关于“方法应该有多少行”主题的思想实验,我想尝试想象一个涉及1,000个不连续步骤的业务操作。每个都在相同的抽象层次上,每个都是明确定义的,并且在它自己的名称很好的方法中等等。那会是什么样子?好吧,对我来说,这将是一个单行(也很有名)的方法,有1000行代码。逐行读取的代码行,类似于特定业务操作的指令集。
当然,我也从未在现实世界中看到 。这是极端的另一端。但作为一个思想实验,它说明了这一点。正在执行的业务操作并不总是与特定模型一对一。它并不总是一个原子步骤。它可以是很多步骤,并且可能相当复杂。 (请记住,复杂的事情是由许多简单的事情组成的。)
为此,在同一个思想实验中,交易管理将在何处进行?当然,包含在这1000行代码中。整个操作是 business -atomic,因为它是通过用户单击按钮调用的,并且应该完全成功或失败。
在某些情况下,您可能无法管理存储库中的事务。但我认为这仅仅是巧合。对于该代码库来说可能是一个方便的巧合(至少在它没有之前),但不能被视为佳能。
由于应用程序提供了业务操作接口,因此它应该真正负责这些操作的原子性。
答案 3 :(得分:0)
交易在应用层上的原因之一是ApplicationService
的执行通常会更改一个Aggregate
,而此Aggregate
会发布DomainEvents
必须在同一交易中按Aggregates
存储。