在Karaf中使用xa交易

时间:2017-05-16 21:46:21

标签: apache-camel activemq apache-karaf

我试图在postgres(使用pax-jdbc设置xa数据源)和karaf中的activemq之间创建一个xa事务,使用blueprint和camel。

设置如下:我有一个camel路由接收jms消息,进行一些数据库更新,然后将jms消息发送到另一个队列。然后,另一个队列将读取更新的记录。

问题是第二个队列正在读取旧数据而不是获取更新的数据。

我认为原因是JMS交易正在发布"首先,数据库尚未提交更改。

如果我在第二个队列上放置了Thread.sleep(1000),我总是会读取正确的数据。此外,我相信交易工作正常,如果我在骆驼路线中抛出异常,我看到数据库没有变化,并且jms消息没有被发送,证明它们正在一起工作。

这是我的jta配置和骆驼路线的蓝图:

    <blueprint
    xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"
    xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
    xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
    xsi:schemaLocation="
        http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
        http://aries.apache.org/xmlns/transactions/v2.0.0 http://aries.apache.org/schemas/transaction/transactionv20.xsd">

  <tx:enable/>

  <bean id="resourceManager" class="org.apache.activemq.pool.ActiveMQResourceManager" init-method="recoverResource">
    <property name="transactionManager" ref="jtaTxManager" />
    <property name="connectionFactory" ref="jmsConnectionFactory" />
    <property name="resourceName" value="activemq.localhost" />
  </bean>

  <bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
    <property name="maximumRedeliveries" value="0"/>
  </bean>

  <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
    <property name="brokerURL" value="$ext{brokerUrl}"/>
    <property name="userName" value="karaf"/>
    <property name="password" value="karaf"/>
    <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
  </bean>

  <bean id="jmsXaPoolConnectionFactory" class="org.apache.activemq.pool.JcaPooledConnectionFactory">
    <property name="name" value="activemq.default"/>
    <property name="maxConnections" value="4"/>
    <property name="transactionManager" ref="jtaTxManager"/>
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
  </bean>

  <!-- define the activemq Camel component so we can integrate with the AMQ broker -->
  <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <!-- due to a bug in activemq-camel we must configure using a nested configuration bean -->
    <property name="configuration">
      <bean class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory" ref="jmsXaPoolConnectionFactory"/>
        <!-- JTA transaction manager (Spring interface to Aries-TM) -->
        <property name="transactionManager" ref="springJtaTxManager"/>
        <!-- IMPORTANT: We set local transactions to false, because the JtaTransactionManager
             will take care of enrolling the XA JMS Connection when needed. -->
        <property name="transacted" value="false"/>
        <!-- IMPORTANT: and disable cache level as the JtaTransactionManager needs to control the consumers
             from its JcaPooledConnectionFactory -->
        <property name="cacheLevelName" value="CACHE_NONE"/>
      </bean>
    </property>
  </bean>

  <reference id="jtaTxManager" interface="org.apache.geronimo.transaction.manager.RecoverableTransactionManager"/>
  <reference id="springJtaTxManager" interface="org.springframework.transaction.PlatformTransactionManager"/>

  <bean id="required" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
    <property name="transactionManager" ref="springJtaTxManager"/>
    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
  </bean>

  <camelContext xmlns="http://camel.apache.org/schema/blueprint" id="om-bstask-context" useMDCLogging="true">
    <route id="notificationConsumer">
      <from uri="activemq:queue:incomingNotification"/>
      <transacted ref="required"/>
      <doTry>
            <!-- execute some bd updates -->
            <to uri="activemq:anotherQueue"/>
        <doCatch>
          <exception>java.lang.Exception</exception>
          <handled>
            <constant>false</constant>
          </handled>
          <bean beanType="xxxx.MessagingUtil"
                method="logErrorMessage(${headers.JMSXDeliveryCount}, ${headers.om_txid}, 'incomingNotification', ${exception})"/>
        </doCatch>
        <doFinally>
        </doFinally>
      </doTry>
    </route>
  </camelContext>

</blueprint>

我的设置有问题吗?或者什么可以解释这种行为?

PS我从https://github.com/camelinaction/camelinaction2/blob/master/chapter12/xa-karaf/src/main/resources/OSGI-INF/blueprint/camel-context.xml

获得了配置

0 个答案:

没有答案