XA事务真的是原子的吗?

时间:2013-02-04 06:02:50

标签: activemq apache-camel xa fuseesb

似乎我不完全理解XA事务是如何工作的。我认为它是原子的:我认为当我提交交易时,新消息和新数据将同时可用。

这种误解导致我出现以下问题: 将新行插入到DB中,并将消息发送到事务路由中的队列。在另一条路线中,收到消息。然后,此路由尝试使用在先前路由中插入的行执行一些操作。但它没有看到它们!

配置第二个路由,以便在发生异常时将消息回滚到队列。我看到在第二次运行之后,路线会看到行!

作为结论,我会问下一个问题:

  1. XA事务真的是原子的吗?
  2. 如果不是,我如何为我的交易资源配置提交订单?
  3. 附加说明:此问题可在Fuse ESB / ServiceMix 4.4.1中找到


    2杰克: 我的驼峰上下文配置如下所示:

    <osgi:reference id="osgiPlatformTransactionManager" interface="org.springframework.transaction.PlatformTransactionManager"/>
    <osgi:reference id="osgiJtaTransactionManager" interface="javax.transaction.TransactionManager"/>
    
    <osgi:reference id="myDataSource"
           interface="javax.sql.DataSource"
           filter="(osgi.jndi.service.name=jdbc/postgresXADB)"/>
    
     <bean id="PROPAGATION_MANDATORY" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="osgiPlatformTransactionManager"/>
        <property name="propagationBehaviorName" value="PROPAGATION_MANDATORY"/>
     </bean>
    
     <bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="osgiPlatformTransactionManager"/>
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
     </bean>
    
    <bean id="jmstx" class="org.apache.activemq.camel.component.ActiveMQComponent"> 
        <property name="configuration" ref="jmsTxConfig" /> 
    </bean> 
    
    <bean id="jmsTxConfig" class="org.apache.camel.component.jms.JmsConfiguration"> 
        <property name="connectionFactory" ref="jmsXaPoolConnectionFactory"/> 
        <property name="transactionManager" ref="osgiPlatformTransactionManager"/>
        <property name="transacted" value="false"/>
        <property name="cacheLevelName" value="CACHE_NONE"/>
        <property name="concurrentConsumers" value="${jms.concurrentConsumers}" />
    </bean> 
    
    <bean id="jmsXaPoolConnectionFactory" class="org.apache.activemq.pool.XaPooledConnectionFactory">
        <property name="maxConnections" value="${jms.maxConnections}" />
        <property name="connectionFactory" ref="jmsXaConnectionFactory" />
        <property name="transactionManager" ref="osgiJtaTransactionManager" />
    </bean>
    
    <bean id="jmsXaConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
        <property name="brokerURL" value="${jms.broker.url}"/>
        <property name="redeliveryPolicy">
            <bean class="org.apache.activemq.RedeliveryPolicy">
                <property name="maximumRedeliveries" value="-1"/>
                <property name="initialRedeliveryDelay" value="2000" />
                <property name="redeliveryDelay" value="5000" />
            </bean>
        </property>
    </bean>
    

    DB数据源配置如下:

    <bean id="myDataSource" class="org.postgresql.xa.PGXADataSource">
        <property name="serverName" value="${db.host}"/>
        <property name="databaseName" value="${db.name}"/>
        <property name="portNumber" value="${db.port}"/>
        <property name="user" value="${db.user}"/>
        <property name="password" value="${db.password}"/>
    </bean>
    
    <service ref="myDataSource" interface="javax.sql.XADataSource">
        <service-properties>
            <entry key="osgi.jndi.service.name" value="jdbc/postgresXADB"/>
                <entry key="datasource" value="postgresXADB"/>
        </service-properties>
    </service>
    

1 个答案:

答案 0 :(得分:1)

我不是这方面的专家,但我的观点是,XA仅提供guaruntees的原子性:

  • 发生整个提交或整个提交回滚。
  • 在提交请求返回给调用它的人之前,整个提交/回滚完成。

我认为没有任何关于在同一时刻完成的个人参与者的保证,也没有任何类型的“提交依赖树”保证保证后续处理仅发生在已经提交的参与者上。

我认为要实现你想要的,你可能需要将消息队列放在主要事务之外......这首先破坏了事务的全部要点:(

我认为您可能只需要在下游处理中添加重试/超时循环。另一种方法是探索并发选项,看看是否允许下游事务“看到”上游。

希望这个答案能够提醒那些对这些东西有更多了解的人来填补!