problems starting an XA session with aspects

View: New views
3 Messages — Rating Filter:   Alert me  

problems starting an XA session with aspects

by stevenmaring :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

sorry that I seem to be a recurring PITA here, but I REALLY need to wrap this up ...

I thought that I was having a problem with my pointcuts when I kept getting

Caused by: bitronix.tm.internal.BitronixSystemException: resource 'amq1' cannot be used outside XA transaction scope. Set allowLocalTransactions to true if you want to allow this and you know your resource supports this.
        at bitronix.tm.resource.common.TransactionContextHelper.enlistInCurrentTransaction(TransactionContextHelper.java:58)
        at bitronix.tm.resource.jms.MessageProducerWrapper.enlistResource(MessageProducerWrapper.java:42)
        ... 42 more

but when I added <property name="allowLocalTransactions" value="true" /> to my connection factory I got a different error ... which implies to me that the pointcut is working ...

Caused by: javax.jms.JMSException: Session's XAResource has not been enlisted in a distributed transaction.
        at org.apache.activemq.ActiveMQXASession.doStartTransaction(ActiveMQXASession.java:109)
        at org.apache.activemq.ActiveMQSession.send(ActiveMQSession.java:1601)
        at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:227)
        at org.apache.activemq.ActiveMQMessageProducerSupport.send(ActiveMQMessageProducerSupport.java:241)
        at bitronix.tm.resource.jms.MessageProducerWrapper.send(MessageProducerWrapper.java:59)
        at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597)


        <jaxws:endpoint
                id="voiceRequest"
                implementor="com.ess.tts.voicerequest.VoiceRequestImpl"
                address="/voiceRequest"
        />
       

  <amq:broker useJmx="true">
  <amq:managementContext>
  <amq:managementContext connectorPort="1098" />
  </amq:managementContext>
  <amq:persistenceAdapter>
    <amq:journaledJDBC dataDirectory="amq"/>
    </amq:persistenceAdapter>
    <amq:transportConnectors>
      <amq:transportConnector uri="tcp://localhost:0" />
    </amq:transportConnectors>
  </amq:broker>
 
    <amq:systemUsage>
        <amq:memoryUsage>
            <amq:memoryUsage limit="20 mb"/>
        </amq:memoryUsage>
        <amq:storeUsage>
            <amq:storeUsage limit="1 gb"/>
        </amq:storeUsage>
        <amq:tempUsage>
            <amq:tempUsage limit="100 mb"/>
        </amq:tempUsage>
    </amq:systemUsage>


  <amq:queue id="amqRequestQueue"  physicalName="amqRequestQueue"/>
  <amq:queue id="amqResponseQueue"  physicalName="amqResponseQueue"/>

   
    <bean id="jmsConnectionFactory" class="bitronix.tm.resource.jms.PoolingConnectionFactory" init-method="init" destroy-method="close">
        <property name="className" value="org.apache.activemq.ActiveMQXAConnectionFactory" />
        <property name="uniqueName" value="amq1" />
        <property name="maxPoolSize" value="5" />
        <property name="allowLocalTransactions" value="true" />
        <property name="driverProperties">
            <props>
                <prop key="brokerURL">vm://localhost</prop>
                <prop key="redeliveryPolicy.initialRedeliveryDelay">5000</prop>
                <prop key="redeliveryPolicy.backOffMultiplier">2</prop>
                                <prop key="redeliveryPolicy.useExponentialBackOff">true</prop>
                                <prop key="redeliveryPolicy.maximumRedeliveries">3</prop>
                                <prop key="prefetchPolicy.queuePrefetch">1</prop>
            </props>
        </property>
    </bean>
   
  <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
  <property name="connectionFactory" ref="jmsConnectionFactory"/>
  </bean>
 
  <bean id="voiceRequestImpl" class="com.ess.tts.voicerequest.VoiceRequestImpl">
  <property name="jmsTemplate" ref="jmsTemplate"/>
  <property name="requestQueue" ref="amqRequestQueue"/>
  </bean>
 
  <bean id="voiceRequestConsumer" class="com.ess.tts.voicerequest.queue.VoiceRequestConsumer">
  <property name="jmsTemplate" ref="jmsTemplate"/>
  <property name="responseQueue" ref="amqResponseQueue"/>
  </bean>
 
  <bean id="btmConfig"
  factory-method="getConfiguration"
  class="bitronix.tm.TransactionManagerServices">
                <property name="serverId" value="spring-btm" />
        </bean>

        <bean id="bitronixTransactionManager"
                factory-method="getTransactionManager"
                class="bitronix.tm.TransactionManagerServices"
                depends-on="btmConfig"
                destroy-method="shutdown" />
       
  <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
                <property name="transactionManager" ref="bitronixTransactionManager" />
                <property name="userTransaction" ref="bitronixTransactionManager" />
        </bean>
       
       
        <tx:advice id="txAdvice" transaction-manager="transactionManager">  
                <tx:attributes>  
                        <tx:method name="*" propagation="REQUIRED" />  
                </tx:attributes>  
        </tx:advice>  

        <aop:config>  
                <aop:advisor pointcut="execution(* *.submitVoiceRequest(..))" advice-ref="txAdvice" />
                <aop:advisor pointcut="execution(* *.onMessage(..))" advice-ref="txAdvice" />
        </aop:config>

        <bean id="voiceResponseConsumer" class="com.ess.tts.voiceresponse.queue.VoiceResponseConsumer" />

        <jms:listener-container
                container-type="default"
                concurrency="1-5"
                destination-type="queue"
                prefetch="1"
                transaction-manager="transactionManager"
                connection-factory="jmsConnectionFactory">
                <jms:listener
                        destination="amqRequestQueue"
                        ref="voiceRequestConsumer"/>
                <jms:listener
                        destination="amqResponseQueue"
                        ref="voiceResponseConsumer"/>
        </jms:listener-container>


any thoughts?

-Steve Maring

Re: problems starting an XA session with aspects

by Dennis Brakhane-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


but when I added <property name="allowLocalTransactions" value="true" /> to
my connection factory I got a different error ... which implies to me that
the pointcut is working ...

Nope.

The first exception is thrown when BTM determines that you use a resource without starting a
transaction first. In rare cases, this is what you want, so you can disable this exception
by setting allowLocalTransactions to true. All it does is skipping the exception and
assume you know what you're doing. There still is no transaction started, which is the
reason why you get the second exception, this time JMS is complaining that you didn't
start one.



Re: problems starting an XA session with aspects

by Ludovic Orban :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dennis is right to the point: you're accessing your JMS server outside of XA transactions scope.

BTM does not allow this when allowLocalTransactions is false but ActiveMQ does not support this in any case so this explains why you get JMSException: Session's XAResource has not been enlisted in a distributed transaction when you set allowLocalTransactions to true.

The solution is the fix your AOP pointcut.