在 CQRS 中实现基于集合的约束

2023-12-21

我仍在努力解决与 CQRS 风格架构相关的基本(和已解决)问题:

我们如何实现依赖于的业务规则a set的聚合根?

以预订应用程序为例。它可以帮助您预订音乐会门票、电影座位或餐厅餐桌。在所有情况下,只会有数量有限待售“物品”。

让我们想象一下该事件或地点非常受欢迎。当新活动或新时段开始销售时,预订很快就会到达——也许每秒就有很多。

在查询方面,我们可以大规模扩展,并将预订放入队列中,由自治组件异步处理。首先,当我们从队列中取出预订命令时,我们将接受它们,但在某个时间我们必须开始拒绝其余的.

我们如何知道何时达到极限?

对于每个预订命令,我们必须查询某种商店以确定我们是否可以满足该请求。这意味着我们需要知道当时我们已经收到了多少预订。

但是,如果域存储是非关系数据存储,例如Windows Azure 表存储,我们不能很好地做到这一点SELECT COUNT(*) FROM ...

一种选择是保留分离聚合根它只是跟踪当前计数,如下所示:

  • AR:预订(谁?有多少人?)
  • AR:事件/时段/日期(总计)

第二个聚合根将是第一个聚合根的非规范化聚合,但是当底层数据存储不支持事务时,这些数据很可能在大容量场景中不同步(这就是我们正在尝试的)地址放在第一位)。

一种可能的解决方案是连载处理预订命令,以便一次只处理一个,但这违背了我们的可扩展性(和冗余)目标。

这种情况让我想起了标准的“缺货”情况,但不同之处在于我们不能很好地将预订推迟。活动一旦售完,就已经售完,所以我看不出有什么补偿措施。

我们如何处理这种情况?


经过一段时间的思考后,我终于意识到根本问题与 CQRS 的关系不如与 CQRS 的关系。非交易性不同 REST 服务的性质。

实际上归结为这个问题:如果需要更新多个资源,如果第二次写操作失败,如何确保一致性?

假设我们要按顺序写入资源 A 和资源 B 的更新。

  1. 资源A更新成功
  2. 尝试更新资源 B 失败

第一次写操作遇到异常并不能轻易回滚,那我们该怎么办呢?捕获并抑制异常以对资源 A 执行补偿操作并不是一个可行的选择。首先,它实现起来很复杂,其次,它也不安全:如果由于网络连接失败而发生第一个异常,会发生什么?在这种情况下,我们也无法针对资源 A 编写补偿操作。

关键在于明确幂等性。虽然 Windows Azure 队列不保证正好一次语义上,它们确实保证至少一次语义。这意味着面对间歇性异常,该消息稍后会被replayed.

在前面的场景中,会发生以下情况:

  1. 尝试更新资源 A。但是,重播会被检测到,因此 A 的状态不会受到影响。但是,“写入”操作成功。
  2. 资源B已成功更新。

当所有写操作都是幂等的时,最终一致性可以通过以下方式实现消息重播.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 CQRS 中实现基于集合的约束 的相关文章

随机推荐