在领域驱动设计中强制执行跨多个聚合的不变量(集验证)

2023-12-02

为了说明这个问题,我们使用一个简单的例子:有两个聚合 -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(使用前将#替换为@)

在领域驱动设计中强制执行跨多个聚合的不变量(集验证) 的相关文章

随机推荐

  • 带有 PathMatcher 的 DirectoryStream 不返回任何路径

    尽管我已经看到了很多类似问题的答案 但我无法使以下代码按我认为应该的方式工作 File dataDir new File C User user id PathMatcher pathMatcher FileSystems getDefau
  • 如何快速学习 Prism for Silverlight?

    我需要使用 Prism 制作 Silverlight 应用程序 学习使用 Silverlight Prism 制作简单应用程序的最佳方法是什么 还建议任何同样的好书 谢谢 我也有 daageu 提到的书 也会推荐它 但为了更快地加快学习 P
  • perl 子例程返回 array 和 str 但它们正在合并

    sub process feed my line my lines my last received while 1 if line push lines 1 line 2 else last received line last prin
  • 当文本字段等于字符串时,ios 使按钮更改视图

    我正在制作这种密码来跳过游戏中的关卡 但我不知道需要什么代码来使按钮更改视图控制器 IBAction button id sender if txt text isEqualToString passwordToSkipLevel1 Cod
  • 终止 Java 程序

    我找到了终止 关闭或停止 我的 Java 程序的方法 我找到了两个解决方案 using return 当我想退出或终止我的程序执行时 我添加这个 using 系统 exit 有时我也用过它 我读到系统 exit from 这个问题 所以 我
  • 锚标记的填充

    我有一个 asp net 页面 其代码如下所示
  • 我需要 ETL 吗?

    我们目前使用 Datastage ETL 每天导出包含 15 个表 3 个不同模式 中的数据的 CSV 文本文件 我想知道是否有一种更简单的方法可以在不使用 ETL 的情况下完成此任务 我尝试过脚本拉 它看起来简单 快速 但它又是一个 ET
  • 如何使用 objectMapper 设置 java.time.Instant 的字符串格式?

    我有一个实体java time Instant对于创建的数据字段 Getter Setter AllArgsConstructor NoArgsConstructor EqualsAndHashCode public class Item
  • Javafx 2.2 和雪豹

    我需要在 Mac 计算机上部署 JavaFX2 2 应用程序 OS X 10 7 或更高版本适用于 Java 7u7 OS X 10 6 怎么样 我们有什么解决办法吗 我认为 10 6 可以更新到 Java 6u35 并且我在某处读到 2
  • 如何从使用 /GL 编译的 .obj 文件确定主要编译器版本?

    我试图从以下位置确定 Visual Studio 版本 2002 2003 2005 2008 2010 2012 2013 2015 obj使用链接时间代码生成选项生成的文件 我使用 MSVC2012 生成的文件具有以下 COFF 标头内
  • 在 Javascript 中推送对象

    我需要在 Javascript 中将对象推送到数组 但每次推送都会覆盖我已经添加的相同对象 例如 This is object list var NewIssue This is array var newIssueList functio
  • 从索引的列/行数组填充出现次数矩阵

    我正在寻找一种有效的方法来从两个包含索引的数组创建出现矩阵 一个代表行索引在这个矩阵中 另一个是列矩阵 例如 我有 matrix will be size 4x3 in this example array of rows idxs wit
  • Python 中互斥锁的正确使用

    我从 python 中的多线程开始 或者至少我的脚本可能创建多个线程 这个算法是互斥体的正确用法吗 我还没有测试过这段代码 它可能根本无法工作 我只希望 processData 在一个线程中运行 一次一个 并且主 while 循环继续运行
  • 帐户仅限于 Google Classroom API

    我和我的同事有一个 C WPF 项目 它管理 Google Classroom 中的课程 我们在 Google API 平台中创建项目 我们是该项目的所有者 两者都有 OAuth 2 0 客户端 ID 但这并不重要 我允许 Classroo
  • 简单的 Spring Boot 应用程序中使用了哪种 ApplicationContext 实现?

    我学过 应用程序上下文 的三种常用实现是 FileSystemXmlApplicationContext 该容器加载定义 来自 XML 文件的 bean 这里需要提供完整路径 将 XML bean 配置文件传递给构造函数 ClassPath
  • 表达式中的变量赋值

    这是我的代码 用于生成斐波那契序列中低于 10 000 000 的值 3 fibs 1 1 4 while x fibs 1 fibs 2 lt 10000000 5 fibs append x 我尝试在 while 循环的条件中对 x 进
  • prolog 中的 if else if else 子句类似于 C/C++

    在 C 语言中我有类似的东西 if cond1 else if cond2 else 这在 Prolog 中怎么可能呢 If1 gt Then1 If2 gt Then2 otherwise 请注意 仅当您无法通过不同子句中的模式匹配来表达
  • 无法将 Web 项目添加到 tomcat 服务器“没有可以从服务器添加或删除的资源” - Java 17

    将 Eclipse 2021 9 工作区迁移到 Java 17 后 无法再将 Web 项目添加到 tomcat 服务器 Tomcat版本是9 0 54 所有项目都有 Project Facet 17 和相关的 java 17 JRE 此外
  • 如何在android中播放rtsp url?

    如何在android中播放rtsp url 你可以使用MediaPlayer or VideoView为此 它在模拟器中不起作用 你可以这样做 mediaplayer setDataSource String RTSP if you are
  • 在领域驱动设计中强制执行跨多个聚合的不变量(集验证)

    为了说明这个问题 我们使用一个简单的例子 有两个聚合 Lamp and Socket 必须始终执行以下业务规则 Lamp nor a Socket可以同时连接多次 为了提供适当的命令 我们设想了一个Connector 服务与Connect