problems starting an XA session with aspects

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

problems starting an XA session with aspects

stevenmaring
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
Reply | Threaded
Open this post in threaded view
|

Re: problems starting an XA session with aspects

Dennis Brakhane-2

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.


Reply | Threaded
Open this post in threaded view
|

Re: problems starting an XA session with aspects

Ludovic Orban
Administrator
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.