Announcement Announcement Module
Collapse
No announcement yet.
Non-transactional JMS send inside transacted DefaultMessageListeningContainer thread Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Non-transactional JMS send inside transacted DefaultMessageListeningContainer thread

    I have a Spring 2.5.5 DefaultMessageListeningContainer. The associated listener needs to execute a synchronous JMS request/response before the final commit and/or rollback. I have implemented this synchronous request/response using a SessionCallback and a non-transactional JmsTemplate, which normally works perfectly.

    However in this case, it seems Spring is trying to be too clever, and even though my JmsTemplate is non-transactional, Spring is seeing that the current thread is associated with a JMS transaction, and automatically gives me a session associated with that transaction for the callback. This obviously prevents me from completing the sync request/response because the sync request is never committed to the queue.

    Is there any way for me to force a non-transactional Session for the sync request/response in this situation? Or must I fallback to using the JMS API's directly?

  • #2
    isExposeListenerSession in AbstractPollingMessageListenerContainer

    I've made some progress in understanding this problem...

    AbstractPollingMessageListenerContainer has a property "exposeListenerSession" that can solve my problem by not associating the transactional container Session with the thread.

    However, the property "exposeListenerSession" seems to serve double-duty for two distinct purposes:

    1) To determine whether transactional resources are attached to the thread and therefore exposed to JmsTemplate calls within the listener implementation.

    2) To expose the container session to the SessionAwareMessageListener implementation via the "session" parameter.

    In my use case, I do want to change the behavior of #1 but I don't want to change the behavior of #2 i.e. I want my SessionAwareMessageListener to continue to have access to the transactional container session.

    My use case is indeed solved by splitting this property into two (I "patched" Spring by overriding DefaultMessageListenerContainer.doInvokeListener and adding a second property), so that I can turn #1 off and leave #2 on in a mutually exclusive way.

    I believe this should be a change in the Spring distribution.

    Comments?

    Comment


    • #3
      Simple Solution with JmsTransactionManager

      Hi!

      I had the same problem. I found a simple solution without patching Spring. Just use the JmsTransactionManager (for your connection, if not already configured) and TX-annotations:

      Code:
          <bean id="jmsTransactionManager"
                class="org.springframework.jms.connection.JmsTransactionManager">
              <property name="connectionFactory" ref="connectionFactory"/>
          </bean>
          <tx:annotation-driven transaction-manager="jmsTransactionManager"/>
      Then just write a bean wrapping your sync sender methods and annotate these methods:

      Code:
          @Transactional(propagation = Propagation.NOT_SUPPORTED)
          public ... sendSync(...) {
              ...
              jmsTemplate.convertAndSend(...)
              jmsTemplate.receiveSelectedAndConvert(...)
              ...
      Hope this helps.

      But nevertheless maybe it is good idea if the spring framework would directly provide such a sendSync method in its JmsTemplate.

      Bye, Torsten

      Comment

      Working...
      X