2013-02-04 52 views
2

看来我并不完全了解XA交易的工作原理。我认为这是原子性的:我认为当我提交一个事务时,新的消息和新的数据将在同一时间可用。XA事务真的是原子吗?

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

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

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

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

附加说明:的问题在保险丝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> 
+0

从你在这里描述,它不明显如果您实际配置了XA事务管理器,甚至是两个单独的事务。你能不能粘贴你的代码? –

+0

2杰克:我已经添加了更多细节。 –

回答

1

我不是这个东西的专家,但我认为将是该XA仅规定guaruntees的原子:

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

我不认为任何guaruntee是关于在同一时刻完成的个别参与者,也没有任何种类的“承诺依赖树”保持保证后续处理只发生在承诺的参与者身上。

我觉得达到你想要什么,你可能需要把消息队列的主要事务之外......这破坏了交易的全点放在首位:(

我想你可能只必须在你的下游处理中放置一个重试/超时循环,或者可以探索并发选项来查看你是否允许下游事务“看见”上游。知道这个东西芯片!

+0

谢谢你的回答。我目前使用AMQ_SCHEDULED_DELAY标头作为解决方法。但我希望有更好的解决方案。 –