【问题标题】:Tibco +Spring JMS behavior with ErrorHandler on TransactionRolledBackExceptionTibco +Spring JMS 行为与 TransactionRolledBackException 上的 ErrorHandler
【发布时间】:2014-08-24 00:36:23
【问题描述】:

我想澄清通过 Spring (4.1) JMS 配置使用的 Tibco 总线 (6.1) 的行为 - 指定和不指定 ErrorHandler,以及 TransactionRolledBackException 的特定情况。

我将 JMS 侦听器配置为“事务”模式,如下所示:

<jms:listener-container connection-factory="singleConnectionFactory"                 
     acknowledge="transacted" task-executor="myTaskExecutor" concurrency="${my.queue.concurrency}">
     <jms:listener destination="${queue.destination}" ref="myProcessor" method="processMyMessage" />
</jms:listener-container>

并将队列的“maxRedelivery”设置为 2。

以下是在 myProcessor.processMyMessage() 中处理事件的场景:

  1. 消息处理成功;结果:消息被确认并从队列中删除
  2. 由业务逻辑或 Spring 容器(如 OOM 或 HectorException)引发运行时异常;结果:消息未被确认,放回总线上并重新发送最多 2 次​​li>
  3. org.springframework.jms.TransactionRolledBackException 被抛出(我假设是 Spring) - 因为它是一个运行时异常,所以产生的行为与 2 中的相同。(这是正确的吗?)

现在,我正在添加一个显式 ErrorHandler 以更好地记录一些运行时异常:

<jms:listener-container connection-factory="singleConnectionFactory"                 
     acknowledge="transacted" task-executor="myTaskExecutor" concurrency="${my.queue.concurrency}"
error-handler="myErrorHandler">
     <jms:listener destination="${queue.destination}" ref="myProcessor" method="processMyMessage" />
</jms:listener-container>

还有下面的ErrorHandler实现,我们在这里吞下TransactionRolledBackException:

import org.springframework.jms.TransactionRolledBackException;
import org.springframework.util.ErrorHandler;
public class JMSListenerErrorHandler implements ErrorHandler {
    @Override
    public void handleError(Throwable t) {
        if (t.getCause() instanceof TransactionRolledBackException) {
            log.warn("JMS transaction rollback; reason: " + t.getMessage(), t);
        } else {
            log.error(t.getMessage(), t);
            throw new RuntimeException(t);
        }
    }

每个用例会发生什么?这是我的猜测:

  1. 没有变化
  2. 没有变化 - 重新抛出此运行时异常,因此消息不会被确认,最多会重新传递 2 次​​li>
  3. TransactionRolledBackException:当我在 ErrorHandler 中处理此异常时 - 这是在 TX 已经回滚(正如 RolledBack 的名称所暗示的那样)并且消息被标记为未确认之后发生的,因此,导致它被重新传递,如案例 2. ?或者我是否通过吞下此异常有效地导致此消息被确认?

几个问题:

  • Spring 在什么情况下会抛出 org.springframework.jms.TransactionRolledBackException ?
  • TransactionRolledBackException 的处理方式是否与任何其他运行时异常不同?

谢谢,

码头

【问题讨论】:

    标签: jms spring-jms tibco


    【解决方案1】:

    Spring JMS 仅在底层 JMS 客户端抛出 javax.jms.TransactionRolledBackException 时抛出该异常 - 它只是一个未经检查的包装异常 - 请参阅 JmxUtils.convertJmsAccessException()

    查看堆栈跟踪,您将了解它被抛出的位置/原因。

    一般来说,即如果它被抛出到容器的会话中,捕获它不会有任何效果 - 事务已经回滚;但堆栈跟踪是关键。

    【讨论】:

    • 谢谢,加里。那么,您是说消息的实际回滚将取决于从哪里抛出 TransactionTolledBackException ?我也不清楚这个异常的处理(回滚或不回滚 TX 和 ACK 消息)是否是其他运行时异常(如 OOM)的不同形式的处理......
    • OOM 是 en Error 不是一个例外(你不能真正“处理”它)。您需要查看堆栈跟踪以确定谁扔了javax.jmx.TransactionRollbackException;我无法推测。该异常表明事务已经回滚,因此您无能为力(除非它在不同的 JMS 会话上)。
    猜你喜欢
    • 2020-11-25
    • 2011-02-20
    • 2017-03-31
    • 2017-02-11
    • 1970-01-01
    • 2017-01-23
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多