Spring 使用@JmsListener时将消息重新传递到MQ

Spring 使用@JmsListener时将消息重新传递到MQ,spring,jms,listener,ibm-mq,Spring,Jms,Listener,Ibm Mq,根据教程,我正在使用@EnableJms和@JmsListener注释在我的应用程序中注册一个队列侦听器。我正在连接到IBMMQ,使用jndi获取连接工厂。我读过关于确认模式等的书,但对我来说还是一件新鲜事。我的问题是消息没有返回到队列(监听器再也不会被调用) 任何帮助都将不胜感激。 我还有第二个问题。据我所知,如果我想在数据库上实现任何操作,回滚提交(如果在此之后出现问题)的唯一方法是创建事务管理器?如果没有,我需要检测重复的消息。我创建了简单的Spring Boot应用程序和IBM MQ的D

根据教程,我正在使用@EnableJms和@JmsListener注释在我的应用程序中注册一个队列侦听器。我正在连接到IBMMQ,使用jndi获取连接工厂。我读过关于确认模式等的书,但对我来说还是一件新鲜事。我的问题是消息没有返回到队列(监听器再也不会被调用)

任何帮助都将不胜感激。
我还有第二个问题。据我所知,如果我想在数据库上实现任何操作,回滚提交(如果在此之后出现问题)的唯一方法是创建事务管理器?如果没有,我需要检测重复的消息。

我创建了简单的Spring Boot应用程序和IBM MQ的Docker容器来测试您的案例。 我在本教程中找到了很好的说明:

在您的例子中,这个环境的行为和预期的一样:接收消息->NullPointerException->返回消息->的无休止循环

我发现了IBM MQ名为“回退队列和阈值”的功能,您可以在这篇博文中找到解释:

简单地说,可以限制异常后消息返回队列的次数,并在此限制后将消息发送到另一个队列


在您的情况下,此功能可能用于您的目标队列。

首先将确认模式设置为
会话。客户端确认
接收消息时,如果处理正确,则只需调用
message.acknowledge()
method,否则不要调用

它将自动留在队列中,您无需重新发送

你需要使用

import javax.jms.Message

我不确定我是否理解你想要实现的目标。@artild提供的答案会让我明白,您试图导致失败,以便您可以看到返回队列的消息,对吗?如果会话被处理,那么在您读取/处理消息后,您必须调用commit将其从队列中删除。SessionAcknowledgeMode仅用于非事务性会话,事务性会话将忽略它。您可以使用一个特殊值来更好地指示它被忽略,它是
Session.transactived
,但此字段中的值对于事务性会话来说永远都不重要<代码>会话。客户端确认仅适用于非事务会话。从IBM MQ的角度来看,与会话进行事务处理和非事务处理。客户端确认类似,最大的区别在于事务会话可以在事务中包含写入。对于IBM MQ,这意味着您可以让侦听器使用一条消息,然后将其放入第二个队列,例如,如果它们都位于同一队列管理器上,那么提交将使消息的GET和put作为一个工作单元发生,这不能用非事务处理的
会话来完成。客户端\u确认
。在我的示例中,如果队列位于两个不同的队列管理器上,或者像您的第二个问题一样,如果您使用消息,然后要更新数据库,则需要一个事务管理器。事务管理器的任务是将GET从队列提交到第二个队列,或将PUT作为单个工作单元更新到数据库。请注意,如果您有权查看队列上的消息,则可以检查消息的回退计数,以查看它已回滚到队列的次数。
import javax.jms.Message