【问题标题】:Is an XA transaction really atomic?XA 事务真的是原子的吗?
【发布时间】:2013-02-04 06:02:49
【问题描述】:

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

这种误解导致我遇到以下问题: 新行被插入到数据库中,并且一条消息被发送到事务路由中的队列。在另一条路线中接收到消息。然后此路由尝试对插入前一个路由的行执行一些操作。但它没有看到它们!

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

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

  1. XA 事务真的是原子的吗?
  2. 如果不是,如何为我的事务资源配置提交顺序?

附加说明:该问题在 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>

【问题讨论】:

  • 根据您在此处的描述,您是否实际配置了一个 XA 事务管理器,甚至两个单独的事务,是否正确并不清楚。你能把你的代码贴上来吗?
  • 2 Jake:我添加了更多细节。

标签: activemq apache-camel xa fuseesb


【解决方案1】:

我不是这方面的专家,但我认为 XA 提供的原子性只能保证:

  • 要么发生整个提交,要么回滚整个提交。
  • 整个提交/回滚在提交请求返回给调用者之前完成。

我认为不会对单个参与者在同一时刻完成做出任何保证,也没有维护任何类型的“提交依赖树”来保证后续处理只发生在已提交的参与者身上。

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

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

希望这个答案能促使对这些东西有更多了解的人参与进来!

【讨论】:

  • 感谢您的回答。我目前使用 AMQ_SCHEDULED_DELAY 标头作为解决方法。但我希望有更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
相关资源
最近更新 更多