2013-02-04 93 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標頭作爲解決方法。但我希望有更好的解決方案。 –