为了说明这个问题,我们使用一个简单的例子:有两个聚合 -Lamp
and Socket
。必须始终执行以下业务规则:Lamp
nor a Socket
可以同时连接多次。为了提供适当的命令,我们设想了一个Connector
- 服务与Connect(Lamp, Socket)
- 堵塞它们的方法。
因为我们希望遵守一笔交易只涉及一个聚合的规则,所以不建议在Connect
-交易。所以我们需要一个中间聚合来象征Connection
本身。所以Connect
- 交易只会创建一个新的Connection
与给定的组件。不幸的是,此时麻烦开始了;如何保证连接状态的一致性?可能会发生许多并发用户想要在同一时间插入相同的组件,因此我们的“一致性检查”不会拒绝该请求。新的Connection
-aggregates 将被存储,因为我们只锁定聚合级别。即使不知道这一点,系统也会不一致。
但是我们应该如何设定聚合的边界来确保我们的业务规则呢?我们可以设想一个Connections
-aggregate 收集所有活动连接(如Connection
-entity),从而启用我们的锁定算法,该算法将正确拒绝重复Connect
-要求。另一方面,这种方法效率低下且无法扩展,而且在领域语言方面也是违反直觉的。
你知道我错过了什么吗?
Edit:总结一下这个问题,想象一个聚合User
。由于聚合的定义是基于事务的单元,我们可以通过锁定每个事务的该单元来强制不变量。一切皆好。但现在出现了一条业务规则:用户名必须是唯一的。因此,我们必须以某种方式使我们的总体边界与这一新要求相协调。假设有数百万用户同时注册,这就成了一个问题。我们尝试确保非锁定状态下的这种不变性,因为多个用户意味着多个聚合。
根据 Eric Evans 所著的《领域驱动设计》一书,一旦单个事务中涉及多个聚合,就应该应用最终一致性。但这真的是这样吗?这有道理吗?
在这里应用最终一致性需要注册User
然后用用户名检查不变量。如果两个User
实际上设置了相同的用户名,系统将撤消第二次注册并通知User
。想到这种情况让我感到不安,因为它扰乱了整个注册过程。例如,发送确认电子邮件必须延迟等等。
我想我只是忘记了一些一般的事情,但我不知道是什么。在我看来,我需要类似不变量的东西Repository
-level.
我们可以设想一个连接聚合,它收集所有活动的连接
连接(作为连接实体),从而使我们能够
锁定算法可以正确拒绝重复
连接请求。另一方面,这种方法效率低下并且
无法扩展,而且在领域方面也是违反直觉的
语言
相反,我认为您采用这种方法是正确的。这看起来很复杂,因为您使用的示例没有任何意义 - 现实生活中没有系统可以检查一盏灯是否连接到多个插座或一个插座是否连接到多个灯。
但是将该方法应用于第二个示例会导致您问自己在这种情况下“连接”聚合是什么,即在哪个范围内用户名是唯一的。在一个Company
?对于给定的Tenant
or Customer
?对于整体来说<whatever-subdomain-youre-in>System
?找到范围的名称,您就拥有了它 - 一个聚合以强制执行唯一名称不变式。仔细选择名称,如果通用语言中尚不存在该名称,请在领域专家的帮助下发明一个新概念。 DDD 不仅尊重现有的领域术语,还允许您在以下情况下引入新的领域术语:突破都实现了。
但有时,您会发现对此聚合的并发访问过于密集,并会产生有问题的争用。通过领域专家的同意,您可以在发生冲突时通过补偿操作引入最终一致性 - 例如,在昵称后附加后缀并通知用户。或者你可以拆分“热”聚合转变为更小、更智能、更高效的企业。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)