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

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(使用前将#替换为@)

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

  • 总结树上的值

    我使用树控件来查看一些基于嵌套 父子 表的分层项目 每个节点都有一个 NameValue 格式 接受 name 和 value 但只有叶子 最后一个节点 具有整数值 并且父节点的值保留为空 仅是它们具有的名称 我想总结值 以便每个父节点都保
  • SQL聚合函数选择唯一值

    我有一个包含两列的行集 technical id and natural id 行集实际上是复杂查询的结果 假设列值之间的映射是双射的 即对于具有相同值的两行 technical id the natural ids 也相同 对于不同的te
  • BL 服务:异常还是方法结果?

    最好的方法是什么 为什么 V1 try var service IoC Resolve
  • 聚合返回空数组 - 猫鼬

    我有以下两个简单的查询 Comment aggregate match id req params id exec function err result result is empty Comment find id req params
  • DDD建模,聚合根之间的交互

    Marked my aggregate roots with 1 2 3 Looks quite nice almost like grapes 我不喜欢的是一个标有红色箭头的实体 让我们想象一下 AR 1 是公司 AR 2 是办公室 AR
  • 选择未聚合的变量,功能上依赖于 GROUPing 变量

    背景 我正在一个非常受限的 T SQL 环境中工作 其中只能定义一个对象的 主体 VIEW 大概是 in CREATE VIEW My View AS 在引擎盖下 这是我的 VERSION https learn microsoft com
  • 如何定义分层数据结构的DDD聚合根?

    我目前正在尝试将领域驱动设计原则应用于我的开发实践 我一直致力于如何为按层次结构组织的数据定义聚合根 我们以文件夹结构为例 每个文件夹可以有 0 N 个子文件夹 子文件夹 0 N 也可以有 0 N 个子文件夹 依此类推 我对文件夹及其所有直
  • 是否可以组合“两个具有聚合和分组依据的查询”(结果集)?

    1 Select id count as totalX FROM my table WHERE x factor 1 GROUP BY id 结果集 id totalX 9 34 10 6 11 21 12 3 2 Select id co
  • 使用 Hibernate 映射双向列表

    我不明白映射双向列表时 Hibernate 的行为 Hibernate 生成的 SQL 语句对我来说似乎不是最佳的 有人可以启发我吗 场景如下 我有一对多的父子关系 我用双向列表来映射这种关系 根据Hibernate 注解参考指南 http
  • 实体框架:获取存储库中的子类对象

    我有与下面列出的数据库表对应的以下模型 经理就是雇员 会计师也是雇员 让所有管理器都进入存储库的最佳方法是什么 如何实现GetAllManagers 方法 这是正确的TPT吗 CODE MyRepository MyEmployeeRepo
  • 再次将服务注入域对象

    我有一个对地理数据进行操作的特定域 我正在 TypeScript 和 NodeJS 中实现这个项目 并有以下类 Point 包含纬度和经度的值对象 Area 包含点集作为形状定义的值对象 Sector 实体 它不是持久的 但它是可变的 包含
  • 实体框架中的聚合根支持

    我们如何告诉实体框架骨料 http domaindrivendesign org node 88 保存聚合时 保存聚合内的实体 删除聚合时 删除聚合内的实体 当两个不同的用户尝试修改同一聚合中的两个不同实体时引发并发错误 加载聚合时 即使在
  • 为什么实体框架需要 ICollection 来延迟加载?

    我想编写一个丰富的域类 例如 public class Product public IEnumerable
  • 事件源和 SQL Server 多个关系表

    我们使用 SQL Server 2016 的事件源 我们有完整的客户产品应用程序 每个应用程序都标记为CustomerId并在事件商店中获取单个指南行项目 这是写入事件存储指南的主要标识符 产品应用程序附带许多不同的关系事物 没有引导 但有
  • DDD 聚合和值对象

    我想问一下关于DDD功能的问题 假设我们有两个聚合 每个聚合都包含值对象地址 根据 Eric Evans DDD 我们应该将聚合彼此隔离 因此第一个聚合的聚合根不能有指向 Address 的链接 坦白说 这对我来说似乎没有意义 所以问题是如
  • Spark:Aggregator和UDAF有什么区别?

    在Spark的文档中 Aggregator 抽象类聚合器 IN BUF OUT 扩展可序列化 用户定义聚合的基类 可以是 在数据集操作中用于获取组中的所有元素并 将它们减少到单个值 用户定义的聚合函数是 抽象类 UserDefinedAgg
  • 具有持久性无知对象的持久性和领域事件

    我一直在研究领域驱动设计领域事件 http www udidahan com 2009 06 14 domain events salvation 我真的很喜欢这些事件提供的关注点分离 我遇到了保留域对象和引发域事件的顺序问题 我想在域对象
  • CQRS - 读取端的事件重播

    我读过几篇关于 CQRS 的博客 它们都解释说 在写入端 事件会持久保存在事件存储中 并且根据请求 事件将被检索并聚合重播 我的问题是为什么读取端不需要聚合事件重播 因为您的读取端不使用聚合 读取端实现为投影 它根据聚合发出的事件流计算当前
  • 是否可以在不改变作为框架一部分的 DDD 模型的情况下使用 NHibernate

    我挖掘了很多关于DDD方法 无处不在的语言 聚合 存储库等 我认为 与我读到的很多内容相反 实体应该有行为而不是不可知论 我看到的所有例子都倾向于呈现实体虚拟自动属性 and an 空构造函数 受保护或最糟糕的是公开 就是这样 我认为这种对
  • 对聚合根内实体的操作

    如果我设计了如下所示的 AR 您认为我应该如何更新订单行对象之一中的属性 例如 我如何更改订单行之一的标题 示例问题 这是订单聚合根 public class Order private readonly int id private re

随机推荐

  • 带有 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