non-transacted asynchronous JMS consumer - Auto_Acknowledge - message not going back on queue

StackOverflow https://stackoverflow.com/questions/20076971

  •  31-07-2022
  •  | 
  •  

سؤال

I'm using Weblogic 12, and I've got a non-transacted asynchronous JMS consumer. I haven't setup the ack mode so it defaults to AUTO_ACKNOWLEDGE. I've confirmed this in the application.. see below.

What I have done is to consume the message and then call exit to quit.

I would expect that the JMS message would be on the queue after this consumer has run as the message should not be acknowledged until such time as the onMessage has fully completed.

Instead the message no longer exists on the Weblogic JMS queue. Any ideas why not???

See below for my onMessage code and the output from the application.

Thanks for the help.

Here is my code

@Override
public void onMessage(Message message, Session session) throws JMSException {

    logger.info("Session : Ack Mode    : " + convertSamToString(session.getAcknowledgeMode()));
    logger.info("Session : Transacted? : " +  session.getTransacted());

    try {
        String msgText;
        if (message instanceof TextMessage) {
            msgText = ((TextMessage) message).getText();
        } else {
            msgText = message.toString();
            messages.add(msgText);
        }

        logger.info("<Msg_Receiver> [" + msgText + "]");

        if (true)
            System.exit(2);
               // throw new RuntimeException("Exception during message consumption.");

    } catch (JMSException jmsEx) {
        logger.error("JMS Exception: ", jmsEx);
        throw new RuntimeException(jmsEx);
    }

    logger.info("Finished processing message.");
}

Here is the output:

19 Nov 2013 16:24:26,079  INFO JmsConsumerApp - JmsConsumerApp starting.
19 Nov 2013 16:24:26,125  INFO ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@19616c7: startup date [Tue Nov 19 16:24:26 GMT 2013]; root of context hierarchy
19 Nov 2013 16:24:26,172  INFO XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [jmsConsumer-applicationContext.xml]
19 Nov 2013 16:24:26,360  INFO PropertyPlaceholderConfigurer - Loading properties file from class path resource [jms.properties]
19 Nov 2013 16:24:26,360  INFO DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@8acf6e: defining beans [org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor#0,jmsconfig,jndiTemplate,connectionFactory,jmsTransactionManager,paymentQueue,jmsConsumer,jmsConsumer1,jmsProducerListenerContainer1]; root of factory hierarchy
19 Nov 2013 16:24:26,750  INFO DefaultLifecycleProcessor - Starting beans in phase 2147483647
19 Nov 2013 16:26:22,433  INFO JmsMessageConsumer1 - Session : Ack Mode    : AUTO_ACKNOWLEDGE
19 Nov 2013 16:26:22,433  INFO JmsMessageConsumer1 - Session : Transacted? : false
19 Nov 2013 16:26:22,433  INFO JmsMessageConsumer1 - <Msg_Receiver> [MyJMStestMessage]
هل كانت مفيدة؟

المحلول 2

I have looked into the JMS 1.1 spec and I see the following text (from 4.4.11):

AUTO_ACKNOWLEDGE - With this option, the session automatically
acknowledges a client’s receipt of a message when it has either successfully
returned from a call to receive or the MessageListener it has called to process
the message successfully returns.

What wasn't obvious from my original question was that I was using Spring's DefaultMessageListenerContainer which has been designed for use with transactions. When not used within a transaction it will immediately ack a message on receipt and before processing (first AUTO_ACK behavior described above).

I changed my spring config to use the jms listener container SimpleMessageListenerContainer and the ack isn't sent until after the messages has been fully processed. Perfect.

The alternative as Nicholas says, is to use a transacted listener.

نصائح أخرى

Auto-Acknowledge means the message is considered delivered as soon as hits code line 1 of your onMessage method (or technically, I think, before that, when it hots the container that is managing the message listener). As such, regardless of what happens next, the server considers the message gone.

I am not sure what behaviour you want, but if you're looking for more granular control, you got it with transacted messages, or you could use Client Acknowledged.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top