资讯专栏INFORMATION COLUMN

聚合Aggregate

garfileo / 2289人阅读

摘要:每个事物的范围限定在单个聚合内。当然,记住仅仅因为是两个表的关系设计不易任何方式表明他们是两个聚合。一个捕获这个事件,并在每个指定的聚合上执行命令。尽管如此,不得不诉诸于此解决方案,这表明您的聚合的总体边界并不正确。

什么是聚合:

聚合是一个更大的封装单位,而不仅仅是一个类。每个事物的范围限定在单个聚合内。聚合组件的使用期被界限在整个聚合的生命周期中。
具体的,一个聚合将会处理命令,请求事件,并在其中封装一个状态模型,使其能够实现所需的命令验证,从而维护聚合的不变量(即业务规则)

聚合和聚合根之间有什么区别:

聚合形成对象关系的树或者图。而聚合根是树的“顶”,它总体上说明了聚合并且代表了剩余部分,它很重要因为他是所有通信的地方。

我知道聚合是事务边界,但我真的需要在同一个事务中事务更新两个聚合。我该怎么办?

我们应该重新思考如下:
   ①你的聚合边界
   ②每个聚合的自责
   ③你怎么样才可以侥幸逃脱掉在读的一端或者在一个saga中
   ④你的领域的真实的非功能性的需求
   如果你写了一个解决方案,但是有两个或者多个的聚合以事务的方式耦合了,那么就说明你没有理解聚合

为什么使用GUID作为ID是一个很好的做法?

因为它们(合理)全局唯一,并且可以由服务器或客户端生成。

如何获取新创建的聚合的ID?

这是一个重要的见解,客户端可以生成自己的ID。
如果客户端生成了GUID并且将其放在创建聚合的命令中,这不是一个问题。否则,你需要从适当的读取端进行轮询,其中ID将以最终一致的时间框架出现。显然,这种是比在一开始就生成的方式要
脆弱的多的

我们应该允许聚合间的引用吗?

从真实的“内存引用”的意义而言,当然是不可以的
在写方面,一个真实的从一个聚合到另外一个聚合的内存引用是不对和禁止的。因为聚合的定义不允许到达他自己的外部(如果允许的话,那么意味着聚合不再是事务边界,意味着我可以不再去
思考维护其不变量的能力,他亦阻止了聚合的分隔)
使用字符串标识符引用另一个聚合是可以的。在写方面是没有用的(因为标识符必须被视为不透明的值,因此聚合不能到达自身之外)。读的一端可能自由的使用这些信息来进行有趣的相关性

如何在一组聚合中验证命令?

这是一种再也无法通过聚合进行查询了的常见的副作用,有几个答案:
①客户端验证
②使用读的一端
③使用saga
④如果那些完全不切实际,那么这就该考虑是否是聚合的边界不对

如何保证整体的引用完整性?

你现在仍在思考外来的关系引用,而不是聚合。看最后的那个问题。当然,记住仅仅因为是两个表的关系设计不易任何方式表明他们是两个聚合。聚合设计是不同的

如何确保新创建的用户具有唯一的用户名?

这是一个常见的问题,因为我们明确地不会在写方面执行交叉聚合操作。但是,我们有很多选择:
①创建一个已经分配了用户名字的读取端。让客户端可以交互式的以键入用户名的方式查询读取端。
②创建一个响应式的saga来标记和停用那些不过是以用户名的读本创建的账户(无论是否是极端巧合或者恶意的或者由于客户的错误)
③如果最终的一致性不够快,那么可以考虑在写的一端添加一个小的本地读取方面得标。确保聚合的食物插入该表

当我下订单时,如何验证客户ID是否真的存在?

假设客户和订单都聚集在这里,很明显,订单的聚合是不能验证这个的,因为这意味着到达了聚合之外了
在事实之后检查,在一个记录了‘broken’订单的saga或者仅仅在一个读取端。毕竟,订单的最重要的事实完全的记录它,大概任何关于订单的收件人的有趣的数据将会被复制到订单聚合中
(引用到用户去访问其地址是坏的设计,订单总是用来提供一个特定的地址,无论是否在未来客户改变他们的地址)
能够使用那些被记录在破损订单的数据意味着你有机会来拯救它,扭转局面---这使得比下列命令更有意义,因为违反外键约束!

如何使用单个命令更新一组聚合?

单一的命令是不能操作一组聚合的。
首先,问问自己你是不是真的需要一个命令更新多个聚合,是什么情况导致这个需求。
然而,你是可以这么做的。允许一种新的“批量命令”。在概念上包含你想要发布的命令以及一组您要发布的聚合(指定或明确指定)。写入段不够强大到处理这种批量操作,但是它可以创建相应
的”批量事件”。一个saga捕获这个事件,并在每个指定的聚合上执行命令。当命令失败的时候,saga可以视情况调用rollback或者发送一封邮件。
这种方法有一些优点:我们将批量操作的意图存储在事件存储中。saga自动回滚或等效。
尽管如此,不得不诉诸于此解决方案,这表明您的聚合的总体边界并不正确。你可能想考虑改变你的聚合边界,而不是为此建立一个saga。

什么是分片?

一种在多个写入端节点上分发大量聚合的方式。我们可以很容易地分解聚合,因为它们完全是自立的。
我们可以很容易地分割聚合,因为它们没有任何外部引用。

聚合可以将事件发送到另一个聚合?

不可以
你的聚合和命令处理器这些因素代表性的早已在代码中使这个想法无法表达,但是有一个更深层次的哲学原因:
    回去重新读第一个问题“what"s an aggregate?”
如果你设法规避命令处理程序,将事件推向另外一个聚合,那么你将会失去聚合的参与验证的变化的机会。这就是为什么我们仅仅允许聚合器上的命令处理程序验证的命令创建事件。

我能从我的聚合中调用一个读取端吗??

不可以

在CQRS系统中我们么发送email

在聚合之外的时间处理器,不要早命令处理程序中执行此操作,就像这个事件由于丢掉了与其他命令竞争而不会被持久化,所以email将会在一个虚假的前提下被发送。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69915.html

相关文章

  • django 1.8 官方文档翻译: 2-5-4 聚合

    摘要:查询集参考中列出了聚合函数的列表。键的名称是按照字段和聚合函数的名称自动生成出来的。例如,要得到每个书店的价格区别,可以使用如下注解这段代码告诉获取书店模型,并连接通过多对多关系图书模型,然后对每本书的价格进行聚合,得出最小值和最大值。 Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http...

    Tonny 评论0 收藏0
  • 聚合管道aggregate

    摘要:聚合管道介绍的聚合管道将文档在一个管道处理完毕后将结果传递给下一个管道处理。它是数据聚合的一个新框架,其概念类似于数据处理的管道。 聚合管道aggregate aggregate介绍 MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。aggreg...

    Me_Kun 评论0 收藏0
  • mongodb中的aggregate(聚合查询)

    摘要:什么是类似于拆分结果然后对结果进行分析求值然后再返回新结果文档聚合官方运用篇个人总结案例一案例二案例三案例那么有什么作用呢举个例子文档中有如下几个集合集合一集合二集合三我们想筛选出中为的集合理所当然我们会这样写当然这样写是能拿到结 什么是aggregate aggregate类似于pipe.拆分结果然后对结果进行分析求值然后再返回新结果.. 文档 MongoDB聚合官方APIMongo...

    leanote 评论0 收藏0
  • mongodb中的aggregate(聚合查询)

    摘要:什么是类似于拆分结果然后对结果进行分析求值然后再返回新结果文档聚合官方运用篇个人总结案例一案例二案例三案例那么有什么作用呢举个例子文档中有如下几个集合集合一集合二集合三我们想筛选出中为的集合理所当然我们会这样写当然这样写是能拿到结 什么是aggregate aggregate类似于pipe.拆分结果然后对结果进行分析求值然后再返回新结果.. 文档 MongoDB聚合官方APIMongo...

    Seay 评论0 收藏0

发表评论

0条评论

garfileo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<