2012-02-10 157 views
13

我有一個運行在jboss上的spring web應用程序,當前配置爲使用HibernateTransactionManager用於db事務,JmsTransactionManager用於jms。對於jms我們使用Camel和ActiveMQ,我們的數據庫是DB2。在一個事務中,我需要向數據庫寫入一些記錄併發送兩個異步的jms消息。 jms消息是事件通知,我只希望在數據庫事務提交時發送它們。春季交易JDBC和JMS的同步

我願意接受在jdbc事務已經提交之後與代理通信失敗的風險(因此沒有發送消息但提交了數據庫),所以我不認爲我需要適當的XA。

我相信我需要的是使用spring事務同步的「盡力而爲」事務管理。

春天的文檔提示,spring會同步兩個事務,並在jdbc事務提交之後提交jms事務 - 但我不認爲它很清楚。這裏的春季文檔http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#tx-resource-synchronization沒有詳細說明它的工作原理。

我發現了一些其他的消息來源,說春天會做我想要的東西,包括一些javadoc下面,我寫了一些集成測試,也顯示它。

http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/jms/support/JmsAccessor.html#setSessionTransacted%28boolean%29 setSessionTransacted在這裏的javadoc聽起來就像我想要的。

從我所看到的,我認爲與成交套數設置爲這樣的真正的創造了駱駝JmsConfiguration足夠:

<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> 
    <property name="connectionFactory" ref="pooledConnectionFactory"/> 
    <property name="transacted" value="true"/> 
    <property name="concurrentConsumers" value="10"/> 
</bean> 

不過,我需要說服別人我誰是有點懷疑的工作,認爲我集成測試僅適用於記錄不良的副作用,而不是故意的彈簧功能。

所以我的問題是 - 我正確地認爲可以依靠spring來同步事務,並且始終在jdbc事務之後提交jms事務,或者這不是我應該依賴的事情,並且可以指向任何官方文件說清楚了嗎?我想一般來說,這是一個很好的方法來採取還是應該以不同的方式管理這些交易?

+0

你好,你現在有答案嗎? – snowindy 2013-05-16 11:31:04

+0

嗨,不,不是。我還沒有看到任何真正清晰的文檔,這是我想要的,但我們現在正在生產中使用它,沒有任何問題。 – laurie 2013-05-16 14:45:45

回答

3

本文可能對您有所幫助Distributed transactions in Spring, with and without XA。我不認爲它特別涵蓋你的案例 - 發送消息+更新數據庫。

+0

謝謝,我已閱讀過這篇文章幾次。在「盡力而爲1PC」部分,他們提供了兩個春季同步的例子,但在一箇中它們配置了一個TransactionAwareConnectionFactoryProxy,另一個配置了一個ChainedTransactionManager。如果我不需要做任何額外的配置來獲得相同的結果,那麼我寧可不要。 – laurie 2012-02-12 12:14:06

0

如果您正在使用本地事務 而用例是保存到數據庫中,然後發送給JMS

就有可能出現三種情況:剛收到後

  1. 異常(DB和JMS之前)

沒問題,一切都會rolledback

  • 保存到DB後,我們有例外
  • 如果有一個插入操作,就會出現由於多發的行中DB retries.With每次重試中,插入件將done.And爲JMS,消息會去DeadLetterQueue中

  • 保存到數據庫和發送到JMS後,我們有一個例外

    如果插入操作,就會出現在DB多發行由於retries.With每次重試,插件將完成。而對於JMS,消息會去DeadLetterQueue中

  • 現在你不想使用XA,這樣的解決方案可能是

    1)檢查,如果(混亂age.getJmsRedelivered(){...}

    如果不是,過程中它

    如果重新發送,請檢查您是否處理它已經

    檢查數據在數據庫基礎上的消息細節

    注意,重新交付是罕見的是,這種檢查也屬罕見,並且沒有開銷

    2)如果你的方法是冪等,那麼你不需要這個檢查

    和關於XA,XA保證消息被傳遞一次 並在多個資源

    但隨着XA,你必須開銷

    所以,如果你不XA管理,最好是

    同步交易