当前位置: 首页 > 知识库问答 >
问题:

Spring/WebLogic-失败时未重新传递JMS消息

郁吉星
2023-03-14

我正在使用WerbLogic 10.3.5和Spring 3.0实现JMS队列。我有以下Spring配置:

    <!--  JMS Configuration -->
<bean id="paymentlistener" class="com.myproject.service.impl.PaymentListener"/> 

<bean id="paymentlistenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="concurrentConsumers" value="10"/>
    <property name="connectionFactory" ref="paymentConnectionFactory"/>
    <property name="destination" ref="paymentQueue"/>
    <property name="messageListener" ref="paymentlistener"/>
</bean>

<bean id="paymentQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jms/paymentResponseHandlerQueue"/>
    <property name="jndiTemplate" ref="jndiTemplate"/>
</bean>

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
            <prop key="java.naming.provider.url">t3://localhost:7001</prop>
        </props>
    </property>
</bean>

<bean id="paymentConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate"/>
    <property name="jndiName" value="jms/paymentResponseHandlerConnectionFactory"/>
</bean>

<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
    <property name="jndiTemplate" ref="jndiTemplate"/>
    <property name="cache" value="true"/>
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="paymentConnectionFactory"/>
    <property name="destinationResolver" ref="jmsDestinationResolver"/>
    <property name="defaultDestination" ref="paymentQueue"/>
    <property name="sessionAcknowledgeModeName" value="DUPS_OK_ACKNOWLEDGE"/>
    <property name="sessionTransacted" value="true"/>
</bean>

我的消息创建代码如下所示:

    MessageCreator messageCreator = new MessageCreator() {
        public Message createMessage(Session session) throws JMSException {
                logger.debug("Session ack mode: " + session.getAcknowledgeMode());
                return session.createObjectMessage(payment);
        }
    };


    jmsTemplate.send("jms/paymentResponseHandlerQueue", messageCreator);

我的听众是这样的:

@Override
public void onMessage(Message message) { // , Session session
if (!(message instanceof ObjectMessage)) {
    throw new IllegalStateException("The PaymentListener queue expects an object message"); 
}

ObjectMessage objectMessage = (ObjectMessage) message;

try {
    logger.debug("Is Message redelivered:" + objectMessage.getJMSRedelivered ());

    if (objectMessage.getObject() instanceof CreditCardPaymentDTO) {

        logger.debug("Object is of type CreditCardPaymentDTO");

        // The user that just logged in
        CreditCardPaymentDTO payment  = (CreditCardPaymentDTO) objectMessage.getObject();               
        otpCollectorDAO.savePayment(payment);
    }
} catch (JMSException e) {
    logger.error(e);
    throw new RuntimeException(e);
} catch (PaymentResponseException e) {
    logger.error(e);
    throw new RuntimeException(e);
}
}

消息被正确创建,侦听器的onMessage()方法被调用,但是如果逻辑失败,我抛出RuntimeException(),消息不会被重新传递。我尝试了上述代码的许多细微变化(例如设置SessionAcknowledgeMemodeName=SESSION_Transactied并显式回滚事务),但消息从未重新排队。让失败的消息重新传递的诀窍是什么?

共有1个答案

慎俊雄
2023-03-14

我认为您需要将DefaultMessageListenerContainersessionTransactited设置为true

<bean id="paymentlistenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    ...
    <property name="sessionTransacted" value="true"/>
</bean>

你可以在这里找到相关的参考留档。

 类似资料:
  • 我正在读一条来自Solace的信息。我能够成功地阅读信息。假设我正在阅读一条消息,在侦听器线程上读取/处理消息时,应用程序崩溃。那我怎么能在那上面再读一遍那条信息呢。使用下面的代码,我无法再次阅读该消息。下面是我的配置

  • 当BOTHRESH=0时,MQ JMS类是否可以重新传递消息? 使用上述设置,是否可以使用重新传递计数通过应用程序代码管理邮件传递重试?

  • 我读到:http://www.javaworld.com/article/2074123/java-web-development/transaction-and-redelivery-in-jms.html?page=2 "通常,确认特定消息会确认会话接收的所有先前消息"(在客户端确认模式下) “邮件重新传递不是自动的,但在某些情况下会重新传递邮件” 我的问题是: 如何确保每次收到消息时都有一个

  • spring XML中的jmsTemplate定义: 有人对问题有什么建议吗/关于如何实现延迟消息传递的其他想法?谢了!

  • 我们有一个camel路由,在这里我们从输入队列读取消息,处理它,设置一些JMS头(使用exchange.getin().setheader(...)),然后将消息路由到某个输出队列。在MQ故障转移方案期间,将重新传递消息。但是,当重新传递消息时,我前面放置的JMS头丢失了。是否有任何方法可以在重新交付后保留JMS头?

  • 高层体系结构 JMS(生产者/消费者)<---->Artemis(STOMP)<---->Websocket-Broker-Relay-Service<---->STOMP-over-Websocket-client(生产者/消费者)