BTM
  1. BTM
  2. BTM-57

BTM incompatible with Spring's JmsTemplate due to too generic Exceptions

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.3.3
    • Fix Version/s: 2.0.0
    • Labels:
      None
    • Environment:
      Spring 2.5.6
    • Number of attachments :
      0

      Description

      I am trying to get Bitronix TM (1.3.3) working with MySQL (via Hibernate) and ActiveMQ using Spring 2.5.6. I get my MySQL datasource working in separate XA transactions but while trying to produce or consume a JMS message in a transaction I get BTM's JMSException 'cannot commit a resource enlisted in a global transaction'. I did some debugging and found out that this is an exception thrown in BTM's DualSessionWrapper instantiated in JmsPooledConnection. Logically this exception should be caught in JmsUtils.commitIfNecessary(..) method used by Spring's JmsTemplate:

      JmsTemplate
      [...]
      protected Message doReceive(Session session, MessageConsumer consumer) throws JMSException {
      [...]
      if (session.getTransacted()) {
      // Commit necessary - but avoid commit call within a JTA transaction.

      if (isSessionLocallyTransacted(session))

      { JmsUtils.commitIfNecessary(session); }

      }
      [...]
      }

      JmsUtils

      [...]
      public static void commitIfNecessary(Session session) throws JMSException {
      Assert.notNull(session, "Session must not be null");
      try

      { session.commit(); }

      catch (javax.jms.TransactionInProgressException ex)

      { // Ignore -> can only happen in case of a JTA transaction. }
      catch (javax.jms.IllegalStateException ex) { // Ignore -> can only happen in case of a JTA transaction. }

      }
      [...]

      DualSessionWrapper
      [...]
      public void commit() throws JMSException

      { if (isParticipatingInActiveGlobalTransaction()) throw new JMSException("cannot commit a resource enlisted in a global transaction"); getSession().commit(); }

      public void rollback() throws JMSException

      { if (isParticipatingInActiveGlobalTransaction()) throw new JMSException("cannot rollback a resource enlisted in a global transaction"); getSession().rollback(); }

      public void recover() throws JMSException

      { if (isParticipatingInActiveGlobalTransaction()) throw new JMSException("cannot recover a resource enlisted in a global transaction"); getSession().recover(); }

      [..]

      The JMSException is not caught (and it should if I correctly understood the functionning) as only javax.jms.TransactionInProgressException and javax.jms.IllegalStateException are listed in JmsUtils' catch statements. Wouldn't it be more appropriate to throw an javax.jms.TransactionInProgressException instead of JMSException (it's more explicit and... caught by JmsUtils )?

        Activity

        Hide
        Ludovic Orban added a comment -

        Fixed in trunk, thanks for the report.

        I'd be glad if you could test the fix and report the outcome.

        Show
        Ludovic Orban added a comment - Fixed in trunk, thanks for the report. I'd be glad if you could test the fix and report the outcome.
        Hide
        Michal Klimuk added a comment -

        Tested in trunk. Works fine. Thank you

        Show
        Michal Klimuk added a comment - Tested in trunk. Works fine. Thank you

          People

          • Assignee:
            Ludovic Orban
            Reporter:
            Michal Klimuk
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: