Home > Enterprise >  Redeliver message in JMS
Redeliver message in JMS

Time:02-15

I am trying to read a message from Solace .I am able to read message successfully. Suppose I am reading a message and while reading/processing the message on listener thread, the app crashes .Then how can i read that message again on that .With my below code I am not able to read that message again.Below is my configuration

@JmsListener(destination = "myqueue", containerFactory = "jmsContainer", concurrency = "5-10")
    public void onMessage(Message msg) {
        
            String message;
            if (msg instanceof TextMessage) {
                message = ((TextMessage) msg).getText();
                LOG.info("In here START "    message) ;
                Thread.sleep(60000); //I crash my app while thread is sleeping here
                LOG.info("In here END "    msg.getJMSDestination() ) ;
                
            }
            

public class SolaceConfig {

    

    @Bean("solaceJndiTemplate")
    public JndiTemplate solaceJndiTemplate() {
        JndiTemplate solaceJndiTemplate = new JndiTemplate();
    
           // setting user name /password ommitted for brevity

            solaceJndiTemplate.setEnvironment(properties);
            
        
        return solaceJndiTemplate;
    }
    
    
    @Bean
    public JndiObjectFactoryBean solaceConnectionFactory(){
        
        JndiObjectFactoryBean solaceConnectionFactory = new JndiObjectFactoryBean();
        solaceConnectionFactory.setJndiTemplate(solaceJndiTemplate());
        solaceConnectionFactory.setJndiName(getJndiName());
        return solaceConnectionFactory;
    }
    


    @Primary
    @Bean
    public CachingConnectionFactory solaceCachedConnectionFactory(){
        CachingConnectionFactory solaceCachedConnectionFactory = new CachingConnectionFactory();
        solaceCachedConnectionFactory.setTargetConnectionFactory((ConnectionFactory)solaceConnectionFactory().getObject());
        solaceCachedConnectionFactory.setSessionCacheSize(10);
        return solaceCachedConnectionFactory;
    }


    @Bean
    public JmsTemplate jmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate(solaceCachedConnectionFactory());
        jmsTemplate.setDeliveryPersistent(true);
        jmsTemplate.setExplicitQosEnabled(true);
        return jmsTemplate;
    }
    

    @Bean
    public DefaultJmsListenerContainerFactory jmsContainer() {
        DefaultJmsListenerContainerFactory container = new DefaultJmsListenerContainerFactory();
        container.setConnectionFactory(solaceCachedConnectionFactory());
    //container.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
        return container;
    }

CodePudding user response:

When using the DMLC, you should enable transactions (set sessionTransacted) so that the acknowledgment is rolled back.

Otherwise, use a SimpleMessageListenerContainer instead.

See the javadocs https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jms/listener/DefaultMessageListenerContainer.html

It is strongly recommended to either set "sessionTransacted" to "true" or specify an external "transactionManager". See the AbstractMessageListenerContainer javadoc for details on acknowledge modes and native transaction options, as well as the AbstractPollingMessageListenerContainer javadoc for details on configuring an external transaction manager. Note that for the default "AUTO_ACKNOWLEDGE" mode, this container applies automatic message acknowledgment before listener execution, with no redelivery in case of an exception.

  • Related