2

我知道这听起来像听到了 1000 次,但我不这么认为,我真的找不到解决方案:

使用常见的 ejb,我可以使用确认模式手动确认()消息。如果我不这样做,它会重新交付。我过去这样做过,效果很好。

使用 Spring JMS 我有一个问题,似乎我要么可以将重新传递设置为仅在抛出异常或根本不抛出异常时才进行处理。

如何像使用ejb一样实现它?

我的问题是:如果消息被确认,我不希望它被重新传递,即使发生异常。

4

3 回答 3

1

感谢您的回复。但是,除了我使用 Spring 3 和注解配置之外,我完全是这样做的。问题不在于接收,而在于确认。如果我是否使用交易,似乎在接收时会自动确认消息。

我尝试直接扩展 MessageListener 并按照方式..注意工作。

public class JMSListener implements SessionAwareMessageListener<TextMessage> {
...

    @Override
    public void onMessage(TextMessage message, Session session) {
        ...
    }
}

这样我就可以看到会话设置。例如 session.getAcknowledgeMode() 提供客户端确认, session.getTransacted() 提供真或假,具体取决于我设置的内容。但似乎没有任何效果。无论如何,该消息似乎已被确认。

spring 和 jee 的 CLIENT_ACKNOWLEDGE 的 java doc 也有区别。对于春天,写着:

"CLIENT_ACKNOWLEDGE":监听器执行成功后的自动消息确认;在抛出异常的情况下不重新投递。

对于jee,写着:

CLIENT_ACKNOWLEDGE 使用此确认模式,客户端通过调用消息的确认方法来确认已消费的消息。

对我来说,这可能是原因吗?但如果真的是这样(我简直不敢相信),它会让 spring 无法处理消息吗?

于 2015-09-28T08:01:09.873 回答
1

我们可以使用 spring 框架的DefaultMessageListenerContainer来满足您的要求。

请从 Spring 中找到以下文档:

以类似于 EJB 世界中的消息驱动 Bean (MDB) 的方式,消息驱动 POJO (MDP) 充当 JMS 消息的接收者。MDP 上的一个限制(但也参见下面对 MessageListenerAdapter 类的讨论)是它必须实现 javax.jms.MessageListener 接口。另请注意,在您的 POJO 将在多个线程上接收消息的情况下,确保您的实现是线程安全的很重要。

http://docs.spring.io/spring/docs/2.5.x/reference/jms.html#jms-asynchronousMessageReception

以下是我在方法上添加了确认()方法的代码片段。

JMS 侦听器类:

public class MyProjectJMSListener implements MessageListener {
    public void onMessage(Message message) {
        try {
            message.acknowledge();
            //Business logic to be added 
        }
        catch (JMSException ex) {
                throw new RuntimeException(ex);
        }       
    }
}

spring-jms-config.xml

<bean id="messageListener" class="com.myproj.MyProjectJMSListener" />

<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="connectionFactory"/>  <!-- connectionFactory bean class to be added -->
    <property name="destination" ref="my.jms.destination"/> 
    <property name="messageListener" ref="messageListener" />
</bean>
于 2015-09-24T15:55:18.393 回答
0

“sessionAcknowledgeMode”设置为“AUTO_ACKNOWLEDGE”(默认):此模式依赖于容器:对于DefaultMessageListenerContainer,它意味着在侦听器执行之前自动确认消息,在异常情况下不会重新发送,在其他侦听器执行中断的情况下也不会重新发送. 对于 SimpleMessageListenerContainer,这意味着在监听器执行后自动消息确认,在抛出用户异常的情况下不会重新传递,但在监听器执行期间 JVM 死机的情况下可能会重新传递。为了始终如一地安排任何容器变体的重新交付,请考虑“CLIENT_ACKNOWLEDGE”模式或 - 最好 - 将“sessionTransacted”设置为“true”。“sessionAcknowledgeMode”设置为“DUPS_OK_ACKNOWLEDGE”:在 (DefaultMessageListenerContainer) 期间或 (SimpleMessageListenerContainer) 侦听器执行后不久的延迟消息确认;如果抛出用户异常,则不会重新交付,但如果 JVM 在侦听器执行期间死亡,则可能会重新交付。为了始终如一地安排任何容器变体的重新交付,请考虑“CLIENT_ACKNOWLEDGE”模式或 - 最好 - 将“sessionTransacted”设置为“true”。“sessionAcknowledgeMode”设置为“CLIENT_ACKNOWLEDGE”:监听器执行成功后自动消息确认;在引发用户异常以及其他侦听器执行中断(例如 JVM 死亡)的情况下,尽最大努力重新交付。“sessionTransacted”设置为“true”:侦听器执行成功后的事务确认;在引发用户异常以及其他侦听器执行中断(例如 JVM 死机)的情况下保证重新交付。

Spring JMS 框架为消息确认公开了上层抽象。用户只需要关心发生用户异常时是否重新投递消息的场景。

所以,需要注意消息监听容器工厂的bean,并相应配置jms选项。

于 2022-01-28T10:07:53.947 回答