Spring DefaultMessageListenerContainer、ActiveMQ 和消息重新传递

发布于 2024-08-19 15:06:17 字数 1010 浏览 2 评论 0 原文

如果我使用 Spring 的 >DefaultMessageListenerContainer 接收 JMS 消息,我没有收到 JMS消息重新传递,即使我将 sessionAcknowledgeMode 设置为 2。

如果在我的 JavaBean 的 onMessage() 内出现 RuntimeException,则该消息不会在 JMS 提供程序 (ActiveMQ) 内确认,它在队列中保持待处理状态。但它永远不会重新传递,我认为这是由于 Spring 从未调用 session.recover() 造成的,根据 ActiveMQ 的文档 是进行重新传递所必需的。

任何人都可以给我一个提示,如何配置 DefaultMessageListenerContainer 以在发生 RuntimeExceptions 时调用 session.recover() 吗?

谨致问候,
马丁

if I use the DefaultMessageListenerContainer of Spring to recieve JMS messages, I don't get JMS messages redelivered, even if I set sessionAcknowledgeMode to 2.

In case of a RuntimeException within the onMessage() of my JavaBean, the message is not acknowledged within the JMS provider (ActiveMQ), it stays as pending in the queue. But it is never redelivered, which I think is caused by the fact that Spring never calls session.recover(), which according to ActiveMQ's documentation is required to is required for redelivery to happen.

Can anybode give me a hint how I can configure DefaultMessageListenerContainer to call session.recover() in case of RuntimeExceptions?

Best regards,
Martin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寻找我们的幸福 2024-08-26 15:06:17

您表明您正在使用 sessionAcknowledgeMode 2,即 Session.CLIENT_ACKNOWLEDGE。以下语句直接取自 AbstractMessageListenerContainer Javadocs:

  • "CLIENT_ACKNOWLEDGE":监听器执行成功后自动消息确认;抛出异常时不会重新投递。

所以问题不在于 Spring DMLC,而是它在抛出运行时异常时调用 Session.recover() 的能力。您是否可以在侦听器的 onMessage() 方法中使用 try/catch 自己调用 Session.recover() 来处理运行时异常?

更新:

您对样板代码提出了很好的观点。它散布在许多地方并需要重构。难道你不能抽象出这样的代码吗?这是一个常见的解决方案。使用包含带有适当处理的 try/catch 的方法创建一个抽象父类应该可以解决问题。然后只需扩展父类即可根据需要实现尽可能多的自定义处理器。您甚至可以使用 Spring 应用程序上下文以适当的方式将处理器连接在一起。

我在向应用程序添加特定于 Spring 的代码时从来没有遇到过问题,因为它可以在任何地方运行。当我开始使用 Spring 时,这对我来说很重要。它并不特定于任何单个应用程序服务器或 servlet 容器,因此,如果我将 com.ibm 或 com.oracle 导入到我的源代码中,我就不会像使用 Spring 那样将自己编码到一个角落。事实上,我已经将 Spring JMS API 与一个 MOM 一起使用,然后切换到另一个 MOM,除了 JMS 连接工厂定义之外,没有更改任何其他内容。

You indicate that you're using sessionAcknowledgeMode 2 which is Session.CLIENT_ACKNOWLEDGE. The following statement is taken directly from the AbstractMessageListenerContainer Javadocs:

  • "CLIENT_ACKNOWLEDGE": Automatic message acknowledgment after successful listener execution; no redelivery in case of exception thrown.

So the problem is not with the Spring DMLC and it's ability to call Session.recover() when a runtime exception is thrown. Is it possible for you to use a try/catch in your listener's onMessage() method to handle runtime exceptions by calling Session.recover() yourself?

Update:

You make a good point about the boilerplate code. It gets sprinkled in many places and begs to be refactored. Is it not possible for you to abstract such code? This is a common solution. Creating an abstract parent class with a method that contains the try/catch with the appropriate processing should do the trick. Then just extend the parent class to implement as many custom processors as necessary. You can even then wire together the processors in an appropriate manner using your Spring app context.

I've never had a problem adding Spring-specific code to an application because it runs anywhere. This was important for me way back when I began using the Spring. It's not specific to any single app server or servlet container so it's not like I'm coding myself into a corner with Spring the way I am if I import com.ibm or com.oracle into my source code. In fact, I've used the Spring JMS APIs with one MOM and switched to another MOM without changing anything other than the JMS connection factory definition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文