BTM
  1. BTM
  2. BTM-101

Resource pools which fail initialization b/c of incremental recovery cannot be reinitialized

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.0
    • Fix Version/s: 2.1.1
    • Labels:
      None
    • Number of attachments :
      0

      Description

      In this case, a Spring DefaultMessageListenerContainer reading from ActiveMQ is configured. If ActiveMQ is not up when the DefaultMessageListenerContainer starts its work, BTM throws the following exception and the PoolingDataSource is broken:

      2011-02-14 16:11:29,318 DEBUG [org.springframework.jms.listener.DefaultMessageListenerContainer] (midasReconResponseThreadPoolExecutor-0) Initiating transaction rollback on listener exception
      javax.jms.JMSException: error enlisting a MessageConsumerWrapper of a DualSessionWrapper in state ACCESSIBLE of a JmsPooledConnection of pool activemq-midasDWSActiveMQJmsFactory in state ACCESSIBLE with underlying connection ActiveMQConnection {id=ID:csnwas6-3541-1297699535231-0:167,clientId=ID:csnwas6-3541-1297699535231-25:57,started=true}
              at bitronix.tm.resource.jms.MessageConsumerWrapper.enlistResource(MessageConsumerWrapper.java:64)
              at bitronix.tm.resource.jms.MessageConsumerWrapper.receive(MessageConsumerWrapper.java:83)
              at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:405)
              at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:308)
              at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:241)
              at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1056)
              at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:952)
              at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
              at java.lang.Thread.run(Thread.java:662)
      Caused by: bitronix.tm.internal.BitronixSystemException: unknown XAResource org.apache.activemq.TransactionContext@40996815, it does not belong to a registered resource
              at bitronix.tm.BitronixTransaction.enlistResource(BitronixTransaction.java:85)
              at bitronix.tm.resource.common.TransactionContextHelper.enlistInCurrentTransaction(TransactionContextHelper.java:70)
              at bitronix.tm.resource.jms.MessageConsumerWrapper.enlistResource(MessageConsumerWrapper.java:62)
              ... 9 more 
      

        Activity

        Hide
        Ludovic Orban added a comment -

        Analysis shows that when a resource pool (both JDBC and JMS are impacted) is initialized after the TM started, incremental recovery is performed by the ResourceRegistrar. If this fails, ResourceRegistrar refuses to register the resource, the resource object is still created (obviously) but its internal XA pool is not reset to null which prevents the resource from being registered again with the ResourceRegistrar.

        The solution is to catch the RecoveryException thrown by ResourceRegistrar.register() and clean the xa pool object in the catch block before re-throwing the exception.

        Show
        Ludovic Orban added a comment - Analysis shows that when a resource pool (both JDBC and JMS are impacted) is initialized after the TM started, incremental recovery is performed by the ResourceRegistrar. If this fails, ResourceRegistrar refuses to register the resource, the resource object is still created (obviously) but its internal XA pool is not reset to null which prevents the resource from being registered again with the ResourceRegistrar. The solution is to catch the RecoveryException thrown by ResourceRegistrar.register() and clean the xa pool object in the catch block before re-throwing the exception.
        Hide
        Ludovic Orban added a comment -

        fix committed in master branch.

        Show
        Ludovic Orban added a comment - fix committed in master branch.
        Hide
        Ludovic Orban added a comment -

        For posterity:

        This bug was really hard to trigger as it could only happen if the pool's first initialization fails b/c of incremental recovery failre, when a transaction is active and the min pool size is 0.

        Show
        Ludovic Orban added a comment - For posterity: This bug was really hard to trigger as it could only happen if the pool's first initialization fails b/c of incremental recovery failre, when a transaction is active and the min pool size is 0.
        Hide
        Ludovic Orban added a comment -

        fixed and test added.

        Show
        Ludovic Orban added a comment - fixed and test added.

          People

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

            Dates

            • Created:
              Updated:
              Resolved: