gpt4 book ai didi

java - 如何在 DDD 中管理域逻辑和事件之间的事务?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:01:24 26 4
gpt4 key购买 nike

我正在研究 DDD 和事件源中的编程。

我看到一个示例,当调用域逻辑(例如 Order.placeOrder())时,它会发布一个事件(例如 OrderPlaced)。并且该事件将作为事件存储发送到 MQ。

域逻辑 (Order.placeOrder()) 应该是一个原子 API,如果使用 Spring 作为事务管理器,它应该有 @Transactional 注释。

现在我的问题是:

  1. 如何确保数据库更改和事件发送在同一个事务中?即,如果在将数据提交到数据库时出现任何错误,则事件永远不会发送到 MQ。

    我知道有像 XA 或 2 阶段提交这样的解决方案来强制数据库更新并在同一事务中发送 MQ 消息。但现在似乎并没有被广泛使用。

  2. 如果还是用Spring的@Transactional注解,没有XA,是不是事务提交成功后我们再做一些逻辑?这样做的最佳做法是什么?

最佳答案

要拥有一个可靠的系统,必须具备以下两个属性:

  • P1:已发布的领域事件必须描述真实发生的变化(即确保没有幽灵事件四处飞扬)。
  • P2:触发域事件的数据库更改必须导致事件被发布(即不要丢失事件)。

有以下几种可能性可以实现这一点,所有这些都是我自己使用过的或看到在一个项目中使用过的:

  1. 使用与您的应用程序使用相同数据库的消息传递基础架构,以便可以使用单个事务。当一个非常简单的消息传递基础架构就足够了并且团队决定自己构建它时,此解决方案是可行的。

  2. 使用 2 阶段提交。我没有这个不再被使用的印象,但也许很少有人谈论它,因为它不是花哨的技术......

  3. 使用一些巧妙的技巧来确保这两个条件都成立。例如。用我所说的鸡和蛋的解决方案:

    • 总是先同步发布事件,然后保存到数据库。这确保 P2 成立。
    • 然后使用事件处理器检查事件流并检查是否可以在数据库中找到事件。如果不是,则从流中删除该事件。这确保 P1 成立。

解决方案 3 需要仔细设计和审查系统每个部分在故障行为方面做出的保证,因此它可能是最难获得正确的解决方案。但它也是一个非常优雅的解决方案,一旦它起作用。

顺便说一句,我不同意将 Spring 注解添加到域对象,而是添加到各自的应用程序服务。这仅作为旁注。

关于java - 如何在 DDD 中管理域逻辑和事件之间的事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33117902/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com