【问题标题】:Message broker exception handling in session transacted consumer or producer会话交易的消费者或生产者中的消息代理异常处理
【发布时间】:2019-04-06 03:49:22
【问题描述】:

我想在我的 Spring Boot 微服务中使用 SAGA 模式。例如在客户订单中,当订单创建时,会产生像OrderCreatedEvent 这样的事件,然后在客户微服务中,OrderCreatedEvent 上的侦听器更新客户信用并产生CreditUpdateEvent 和...。

我使用会话事务JmsTemplate 进行事件生成。在JmsTemplate的javadoc中说JMS事务在主事务之后提交:

这具有与主事务(可能是本机 JDBC 事务)一起管理本地 JMS 事务的效果,JMS 事务在主事务之后提交。

现在我的问题是如何处理以下情况:

已提交的主要事务(例如已提交的订单)并且系统无法提交 JMS 事务(出于任何原因)。

我想使用 SAGA 而不是两阶段提交,但我认为 SAGA 将问题从订单和客户服务转移到订单服务和 JMS 提供商。

【问题讨论】:

    标签: java spring-boot jms microservices saga


    【解决方案1】:

    使用 SAGA,您希望将交易 (tx) 步骤拆分或重新排序为 3 个阶段:

    1. 您可以对其执行补偿操作的 Tx 步骤。对于每个 T1..N,您都有一个 C1..N
    2. 无法补偿的 Tx 步骤。如果他们失败了,那么你之前触发 定义 C1..N
    3. 始终成功的可重试 Tx 步骤。

    SAGA 不是 ACID,只有 ACD。您需要实现自己的隔离,以防止脏读。通常带有锁定。

    为什么选择 SAGA?避免同步运行时耦合和浇注可用性。您等待最后一个参与者提交。

    要付出相当高昂的代价。

    机会很小,但您仍然可能会遇到可能用于获取聚合的不一致事件。

    【讨论】:

      【解决方案2】:

      SAGA 提示问题:

      还有以下问题需要解决:

      ...

      • 为了可靠,服务必须自动更新其数据库发布事件。它不能使用跨越数据库和消息代理的分布式事务的传统机制。相反,它必须使用下列模式之一。

      ...

      以下模式是原子更新状态和发布事件的方法:

      • 事件溯源
      • 应用程序事件
      • 数据库触发器
      • 事务日志拖尾

      Event Sourcing 在此列表中很特别,因为它彻底改变了您的系统存储和处理数据的方式。通常,系统只存储实体的当前状态。一些系统添加了对具有有效期和/或bitemporal data 的历史状态的显式支持。

      基于事件溯源的系统以允许它从事件重构状态的方式存储事件序列而不是实体状态。只有一个事务资源需要维护 - 事件存储 - 因此无需协调事务。

      列表中的其他模式通过要求事件生产者代码将所有更改(实体状态和事件(作为实体))提交到单个数据存储来避免事务协调问题。然后实现一个专用但独立的机制 - 事件发布者 - 从数据存储中获取事件并将它们发布给事件消费者。

      事件发布者需要跟踪已发布/未发布的事件,这通常会带来协调事务的问题。这就是消费者暴露出来的事件的幂等性。事件发布者将从最后一个已知位置重播事件,而消费者将忽略重复事件。

      您还可以颠倒事件生产者和事件消费者的主动/被动方面。事件生产者将实体状态和事件(作为实体)存储到单个数据存储中,并提供一个端点,允许事件消费者访问事件流。每个事件消费者都跟踪已处理/未处理的事件——出于幂等性的原因,它无论如何都需要这样做——但仅限于它感兴趣的事件流。本书REST in Practice - 第 7 章和第 8 章对这种方法进行了很好的解释。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-31
        • 2021-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-13
        • 1970-01-01
        相关资源
        最近更新 更多