Java 为什么消息再次出现在onMessage()函数中?

Java 为什么消息再次出现在onMessage()函数中?,java,nullpointerexception,jms,listener,activemq,Java,Nullpointerexception,Jms,Listener,Activemq,我正在使用ActiveMQ发送消息 所以当我发送一条消息时,消息就是接收消息。成功插入后,将对其进行确认 但是我在确认之后有代码,它可以抛出NullPointerException 因此,为了故意产生该异常,我抛出了NullPointerException。 因此,当它这样做时: 消息未出列,同一消息再次出现在onMessage函数中 我的代码是: 为什么消息再次出现在onMessage()函数中,就像我的acknowledge()一样 因为我已经在db中插入了消息 队列中的消息是否将在ackn

我正在使用
ActiveMQ
发送消息

所以当我发送一条消息时,消息就是接收消息。成功插入后,将对其进行确认

但是我在确认之后有代码,它可以抛出
NullPointerException

因此,为了故意产生该异常,我抛出了
NullPointerException
。 因此,当它这样做时:

消息未
出列
,同一消息再次出现在
onMessage
函数中

我的代码是:

为什么消息再次出现在
onMessage()
函数中,就像我的
acknowledge()
一样

因为我已经在db中插入了消息

队列中的消息是否将在
acknowledge()
上删除


如何实现这一点?

当您使用事务化JMS确认模式时,JMS侦听器将多次接收您的消息(在AMQ中,默认情况下大约为八次),直到被毫无例外地处理或由JMS容器移动到DQL队列。有关详细信息,请参阅

管理事务取决于您使用的框架。我更喜欢使用,因此我的Spring XML配置如下所示:

<jms:listener-container container-type="default"
                        connection-factory="calendarConnectionFactory"
                        acknowledge="transacted"
                        destination-type="queue"
                        cache="consumer"
                        concurrency="1-5">
    <jms:listener destination="${jms.calendar.destination}" ref="calendarListener"/>
</jms:listener-container>

因此,我可以管理哪些异常将回滚事务。

您对消息侦听器使用自动确认模式,然后根据规范,如果消息侦听器未能成功返回(例如,如果引发异常),将重新传递消息

在您的情况下,您试图手动确认消息,但使用
createSession(false,session.AUTO\u acknowledge)
创建的会话无法手动确认消息

您的代码将与
会话一起使用。客户端\u确认

否则,您希望在使用AUTO_ACKNOWLEDGE时捕获onMessage方法内部的异常


<> >为了在邮件中获得更细粒度的控制,请考虑使用事务处理会话并使用<代码> session >();代码>以确认消息已被读取。

是否已检查您是否正在使用?。使用事务会话时,将忽略确认模式,因此:

  • 您的
    message.acknowledge()
    实际上是一个禁止操作的选项

  • 您的未捕获异常将在转义消息侦听器时触发“会话回滚”,从而强制重新传递消息


注意:您发布的代码有一个catch(Exception ex){},因此我不知道您的异常是如何逃逸到外部的。

您可以创建一个单独的方法来处理消息,我的意思是在
onMessage()
函数中编写代码,以便只将该消息插入数据库

并创建一个单独的函数来处理该消息


这样,如果在处理过程中出现任何错误,消息将不会再次出现在
onMessage()
中。

会话的确认模式是什么?@Tim acknowlge mode设置为Client\u Acknowledge。您使用的是哪个版本的activemq?版本是:apache-activemq-5.6。0@TimBish我仍在寻找答案。如果您知道答案,请告诉我。在我的jms-confif.xml文件中。我已经将其设置为CLIENT_ACKNOWLEDGE,但仍然存在相同的问题。在确认之后,它抛出Nullpointerexception,然后转到catch块。在该消息之后,再次出现onMessage()函数。“您的message.acknowledge()实际上是一个no-op”no-op的意思是什么?@vikiii no-op的意思是“no-operation”。这是一个普通的术语,指的是一些不起任何作用的指令。谢谢你的想法。我会尝试去实现它。
<jms:listener-container container-type="default"
                        connection-factory="calendarConnectionFactory"
                        acknowledge="transacted"
                        destination-type="queue"
                        cache="consumer"
                        concurrency="1-5">
    <jms:listener destination="${jms.calendar.destination}" ref="calendarListener"/>
</jms:listener-container>
@Override
@Transactional(propagation = Propagation.REQUIRED,
               noRollbackFor =
                 {ClassCastException.class, IllegalArgumentException.class})
public void onMessage(Message message) {
 ....
}