Artemis-如何避免非事务会话的TransactionRolledBackException



我使用带有共享存储的实时/备份,并且使用非事务性JMS会话。我总是发送一条消息,我总是收到一条消息然后确认,只有在第一次确认成功后才收到第二条消息。

我在非交易会话中遇到了这个异常:

Execution of JMS message listener failed. Caused by: [javax.jms.TransactionRolledBackException - AMQ219030: The transaction was rolled back on failover to a backup server]
javax.jms.TransactionRolledBackException: AMQ219030: The transaction was rolled back on failover to a backup server
at org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.rollbackOnFailover(ClientSessionImpl.java:904)
at org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.commit(ClientSessionImpl.java:927)
at org.apache.activemq.artemis.jms.client.ActiveMQMessage.acknowledge(ActiveMQMessage.java:719)

这是因为会话被标记为">仅回滚";。经过以下步骤,我得到了这种状态:

  1. 我使用Spring JMS。消费者会话全天候工作(无限循环session.receive()(
  2. 主节点崩溃,然后重新启动主节点
  3. 恢复后(几个小时后(,我向队列发送了一条消息。使用者读取消息并在确认时抛出Exception(因为已标记为仅回滚(
  4. 我再次阅读了这条消息(这对我的任务来说并不是很糟糕(,但重新交付计数并没有增加
  5. 我的消费者代码:
onMessage(Message message) {
if (redeliveryCount(message) > 0){
processAsDublicate(message);  // It's not invoked  - it is error in my business logic.
}
}
  1. 我从另一个代理迁移过来,我想不改变客户端逻辑

问题:

如何避免非事务会话的TransactionRolledBackException?如果这不可能,我应该更改消费者代码吗?

提前感谢

回答后更新

https://github.com/apache/activemq-artemis/tree/2.14.0/examples/features/ha/replicated-failback

这个例子不适合我的情况——我没有未确认的消息。我在以下步骤后得到了这种状态:1(重新启动服务器2(消耗消息3(确认边缘消息

  1. 我们为大约30个应用程序(全天候(使用一个broker,总共有大约200个消费者
  2. 例如,在周末,我们重新启动JMS Broker
  3. 所有消费者在消费新消息后都会开始收到此异常吗(他们没有未确认的消息(

TransactionRolledBackException是预期的,正如您在复制的故障回复示例中看到的那样。

为了防止使用者多次接收相同的消息,必须实现幂等使用者,即ApacheCamel提供了一个可与任何JMS提供者一起使用的幂等使用者组件,请参阅:http://camel.apache.org/idempotent-consumer.html

最新更新