Announcement Announcement Module
No announcement yet.
DefaultMessageListenerContainer errorHandler and recovery Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • DefaultMessageListenerContainer errorHandler and recovery

    Hey all,

    I am trying to configure org.springframework.jms.listener.DefaultMessageLis tenerContainer if there's an exception to try to send it over to a JMS queue first. If it succeeds then there's no need to rollback the transaction, otherwise it would do rollback.

    I am using
    <jms:message-driven-channel-adapter channel="incomingUpdateChannel"
      <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="queueConnectionFactory"/>
        <property name="destination" ref="updatesQueue"/>
        <property name="sessionTransacted" value="true"/>
        <property name="transactionManager" ref="jmsTxManager"/>
        <property name="errorHandler" ref="jmsErrorHandler"/>
     <bean id="jmsErrorHandler"  class="">
        <property name="defaultErrorChannel" ref="errorChannel"/>
      <!-- Transaction Manager Template -->
      <bean id="jmsTxManager" class="org.springframework.jms.connection.JmsTransactionManager">
        <property name="connectionFactory" ref="queueConnectionFactory" />
    Is there a way to replace the current jmsErrorHandler with something that could do what I described above?

    Thanks in advance for your time

  • #2
    You don't need to configure the container like that.

    Simply add an error-channel to the inbound adapter; when an exception occurs on the main flow (incomingUpdateChannel->) an ErrorMessage will be sent to the error-channel. The payload of that message will be a MessagingException and you can extract the failed message to attempt to send to your failures queue. Just add a transformer (expresssion="payload.failedMessage") followed by a jms outbound adapter. If the send is successful the original transaction will commit. If the error-channel flow throws an exception, the original message will be rolled back.

    In either case, you don't need to specify an external JmsTransactionManager - local transactions are sufficient.


    • #3
      Hey Gary,

      Thanks for the quick answer. I tried to configure it like that in order to specify a transactionManager. According to your last statement I don't need that since it's handled by local transactions. Can you elaborate in that (or point me to the correct docs) ?
      The whole application has some moving parts as well as the JMS. It involves Database calls and connection to an external API (server). This is why I wanted to use transactionManager.

      Also as far as I know the jms:inbound-channel-adapter doesn't have an error-channel property to configure, am I missing something? (


      • #4
        Re: transactions - if you want to synchronize the JMS transaction with a JDBC transaction, you need to specify the JDBC transaction manager here, not the JMS transaction manager. Similarly, if you are using an XA transaction manager, you provide that here, NOT a JMS transaction manager. Bear in mind that if you are NOT using an XA transaction manager, you only get 'best effort 1PC'. See The general idea is that the 2 commits (JDBC and JMS) are done as close together as possible, with the JMS transaction being committed immediately after the JDBC. This means there is a (slight) possibility you will have to handle duplicate messages.

        The error channel is shown in the docs you cited. See the sentence starting with "Finally, ..." under


        • #5
          Right, thanks for the explanation Gary. I eventually ended up using a chained transaction manager which combines both the JMS and JDBC txManagers (I didn't want to use XA Transactions).

          About the error channel, my bad I was looking in the wrong place! Thanks for point that out.