0

I am using DMLC to listen to Tibco EMS queues ( Tomcat). After some time, messages are not being delivered. After restarting, messages are delivered again. I am using SingleConnectionFactory.

Connection Factory:
 <bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <property name="jndiName"     value="${connectionQueueFactory}" />
    <property name="cache"  value="false"/>
    <property name="lookupOnStartup" value="false"/>
    <property name="proxyInterface" value="javax.jms.ConnectionFactory"/>
 </bean>

Authenticated Connection Factory:
 <bean id="authenticationConnectionFactory"
    class="com.my.service.AuthenticationConnectionFactory"> <-- extends SingleConnectionFactory
    <property name="targetConnectionFactory" ref="jmsConnectionFactory" />
    <property name="username" value="${userName}" />
    <property name="password" value="${password}" />
    <property name="sessionCacheSize" value="1"/>
 </bean>

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

Container:
<jms:listener-container concurrency="10-15" container-type="default" 
                        connection-factory="simpleAuthenticationConnectionFactory" 
                        destination-type="queue"
                        cache="consumer"
                        prefetch="1"
                        destination-resolver="destinationResolver"
                        acknowledge="transacted">
                 ..... listeners.....
  </jms:listener-container>

Thank you.

1 Answers1

0

acknowledge="transacted" will not confirm the message if an exception is thrown during processing, which can result in this behaviour as the EMS daemon thinks your application is still busy processing the messages that have been delivered but not confirmed.

However transacted is also the only acknowledge mode that guarantees re-delivery in case an exception is thrown.

What this means is that you must not let exceptions be thrown, unless your application is shutting down, which can be a real pain. I've covered off the various options in an article The Chain of Custody Problem. The short version is:

  1. Discard the message and ignore the error;
  2. Send the message (and/or the error) to an error log or queue, which is by monitored by people;
  3. Send the message (and/or the error) to an error queue, which is processed by the sending application.

All of these options have problems, which is why Fire-and-Forget messaging sucks, but in your case you'll probably find option 2 to be the most pragmatic.

Community
  • 1
  • 1
Tom Howard
  • 6,516
  • 35
  • 58
  • Tom,thank you for your answer. However, I do not throw exceptions in my listeners. I catch exceptions and, depending on the exception type, either commit session or roll it back ( using session aware message listener). – user4054431 Oct 05 '14 at 06:49
  • Try listening to the $sys.monitor messages to see what the EMS daemon thinks is happening. Either it's not receiving the confirms or the sessions are not rolling back correctly. – Tom Howard Oct 06 '14 at 11:23