activemq-artemis - 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)
这是因为会话被标记为“ rollbackOnly ”。经过以下步骤后,我得到了这个状态:
- 我使用 Spring-JMS。消费者会话 24/7 工作(无限循环
session.receive()
) - 主节点崩溃,然后主节点重新启动
- 恢复后(几个小时后),我向队列发送了一条消息。消费者阅读消息并在确认时抛出异常(因为被标记为仅回滚)
- 我再次阅读了消息(这对我的任务来说不是很糟糕)但重新投递计数没有增加
- 我的消费者代码:
onMessage(Message message) {
if (redeliveryCount(message) > 0){
processAsDublicate(message); // It's not invoked - it is error in my business logic.
}
}
- 我从另一个代理迁移,并且我认为不更改客户端逻辑
问题:
如何避免非事务性会话的 TransactionRolledBackException?如果这不可能,我应该更改消费者代码吗?
先感谢您
回答后更新:
https://github.com/apache/activemq-artemis/tree/2.14.0/examples/features/ha/replicated-failback
这个例子不适合我的情况——我没有未确认的消息。经过以下步骤后,我得到了这个状态:1)重启服务器 2)消费消息 3)确认消息
- 我们为约 30 个应用程序 (24/7) 使用代理,总共约 200 个消费者
- 比如周末我们重启JMS Broker
- 所有消费者在消费新消息后是否都会开始收到此异常(他们没有未确认的消息)
解决方案
如您在复制故障回复示例中所见,预期会出现 TransactionRolledBackException 。
为了防止消费者多次接收相同的消息,必须实现幂等消费者,即 Apache Camel 提供了可与任何 JMS 提供者一起使用的幂等消费者组件,请参阅:http ://camel.apache.org/idempotent-consumer .html
推荐阅读
- android - 将 sdk 版本从 28 升级到 29 时遇到错误
- amazon-web-services - aws s3 中的长轮询可用吗?
- eigen - vectorXd from_json()?
- c++ - 如何在boost C++中对具有多个参数的函数使用二分法
- python - ImportError:无法导入名称(未知位置)
- emacs - 用于 Windows 10 组织模式的 emacs 27.1 在首次加载期间无法正常工作(Shell 命令成功但没有输出)
- java - 无法从度量查询语言 MQL - GCP 收集数据
- git - 无法在 bonobo git 服务器中使用钩子
- android - Xamarin - Shell.Current.GoToAsync 和后退按钮
- symfony - EasyAdmin 3.X - 如何查看相关实体 `toString` 而不是列表中的关联数?