【问题标题】:Sum on collection invariant prevent Aggregate root creation/update集合不变量的总和阻止聚合根创建/更新
【发布时间】:2020-01-03 08:51:27
【问题描述】:

我知道有很多关于集合验证的主题,我不会说我已经阅读了其中的每一个,但我已经阅读了很多,但仍然觉得我没有看到一些明确的答案闻起来不难闻。

考虑一下:

  • 我们有Customer的概念
  • Customer 有一些一般细节数据
  • Customer可以做Transaction(在店里买东西)
  • 如果Customer 处于信用模式,那么他一年可以消费的金额是有限制的
  • Transactions/Customer 每年的数量可能很大(数千个以上)
  • 至关重要的是,Customer 永远不会花费超过限额的一分钱(没有人会手动检查限额)
  • Customer 可以创建新的 Transaction 或将项目添加到现有的项目中,并且必须检查两者的限制
  • Customer实际上可以是Company,后面有很多Users进行实际交易意味着Transactions可以同时创建/更新

显然,在创建新的或编辑现有的Transaction 时,我想避免为Customer 加载所有Transactions,因为它不能很好地适应大量Transactions

如果我在创建/更新Transaction 之前引入专用于检查currentLimitSpent 的聚合,那么我将进行非事务性创建/更新(一个步骤检查currentLimitSpent,然后另一个检查创建/更新Transaction)。

如果我不关心所有 ddd 规则(或者如果它的最终一致性方法),我知道如何实现这一点,但我想知道是否有一些惯用的 ddd 方法来解决此类问题,且严格一致性不涉及为每个 Transaction 创建/更新加载所有 Transactions

【问题讨论】:

    标签: domain-driven-design microservices


    【解决方案1】:

    至关重要的是,客户永远不会花费超过限额的一分钱(那里 没有人会手动检查限制)

    请阅读这两个帖子:RC Dont ExistEventual Consistency

    如果系统所有者仍然认为必须遵守代码,为避免并发问题,您可以使用存储在持久性中的预先计算的currentLimitSpent(因为您的问题中没有事件源标签)来检查不变量并使用它作为乐观并发标志。

    • 使用currentLimitSpent 和您需要的任何其他持久性数据隐藏您的聚合。

    • 检查规则 (customerMaxCredit <= currentLimitSpent + newTransactionValue)。

    • 坚持 (currentLimitSpent + newTransactionValue) 为新的currentLimitSpent

    • 如果currentLimitSpent 在聚合工作时更改了持久性(同一公司中的许多用户进行交易),您应该会从持久性中得到一个optimisticConcurrency 错误。

    • 您可以停止出现异常或重新隐藏聚合并重试。

    这是一个概述。如果不涉及技术堆栈细节和架构设计,就不能更详细了。

    【讨论】:

    • 感谢您的精彩解释!只是一个澄清,这不是又介绍了两步,非事务性编辑:一个更新currentLimitSpent,一个放置实际Transaction
    • 聚合检查 currentLimitSpent 规则和任何其他规则以创建交易。它的响应将是错误或正常。在 OK 上,聚合响应包含所有需要持久化以使系统保持一致状态的变化数据。这只是每个聚合的一个事务。在持久化方面你应该有一个机制,允许你打开一个持久化引擎事务->持久化新事务->持久化 currentLimitSpent->提交/回滚事务。
    • 尽量不要将聚合(业务事务)的事务概念与持久化引擎的事务混为一谈。
    • “将业务规则泄漏到域外” - 泄漏在哪里?进入持久层?持久层只是以“全有或全无”的行为更新了几个表中的几列。那里没有业务规则。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多