【发布时间】: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() 中处理事件的场景:
- 消息处理成功;结果:消息被确认并从队列中删除
- 由业务逻辑或 Spring 容器(如 OOM 或 HectorException)引发运行时异常;结果:消息未被确认,放回总线上并重新发送最多 2 次li>
- 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);
}
}
每个用例会发生什么?这是我的猜测:
- 没有变化
- 没有变化 - 重新抛出此运行时异常,因此消息不会被确认,最多会重新传递 2 次li>
- TransactionRolledBackException:当我在 ErrorHandler 中处理此异常时 - 这是在 TX 已经回滚(正如 RolledBack 的名称所暗示的那样)并且消息被标记为未确认之后发生的,因此,导致它被重新传递,如案例 2. ?或者我是否通过吞下此异常有效地导致此消息被确认?
几个问题:
- Spring 在什么情况下会抛出 org.springframework.jms.TransactionRolledBackException ?
- TransactionRolledBackException 的处理方式是否与任何其他运行时异常不同?
谢谢,
码头
【问题讨论】:
标签: jms spring-jms tibco