2013-09-30 66 views
1

我正在使用遺留應用程序。我們正在將它從JDBC遷移到Spring 3.2 + Hibernate 4.1.12 + JTA 2並使用聲明式事務。我發現集裝箱管理交易(CMT)正在按照預期進行交易和回滾。我們使用Infinispan作爲二級緩存(2LC)。有一個皺紋...混合使用CMT和BMT的交易管理(BMT案例提交數據過早)

有一部分代碼與不同的入口點在不同的線程中運行,並使用編程事務或Bean管理事務(BMT)。在BMT路徑中,我發現在使用CMT的底層服務層中,這些交易正如人們所期望的那樣與BMT結合在一起。

持久性單元,數據源等對於兩個入口點都是相同的。在這兩種情況下,Hibernate自動刷新代碼都知道存在事務並刷新數據庫驅動程序。在CMT入口點,數據庫驅動程序保存數據直到被告知提交或回滾。在BMT路徑中,數據在刷新時被推入數據庫 - 後面的提交或回滾沒有效果或明顯的含義。事務管理器是JtaTransactionManager。 JtaTransactionManager在具有@EnableTransactionManagement的@Configuration類中定義,以啓用CMT而不是<tx:annotation-driven/>元素。

單身JtaTransactionManager bean通過jtaPropertyManager.getJTAEnvironmentBean().getTransactionManager()jtaPropertyManager.getJTAEnvironmentBean().getUserTransaction()與ajuna UserTransaction和TransactionManager連線。 UserTransaction和TransactionManager都是原型@Bean定義。

我能夠通過另一個查詢工具的查詢來確認數據是否在數據庫中,以驗證調試時的行爲。

當我是單元測試時,數據會按照預期爲BMT和CMT入口點提交和回滾。

BMT由具有以不同方法開始和結束事務的類來管理。它也有執行實際工作單元的方法。 BMT的事務由PlatformTransactionManager啓動,而不是TransactionTemplate。該類由另一個具有邏輯管理邏輯流程的類驅動。我知道交易是按照預期開始和結束的。在閱讀各種其他討論時,似乎暗示交易控制應該在單一方法內。我同意這將是首選,但它是必不可少的?

如果在Spring中由CMT管理的Servlet生成一個新的Thread並使用一個計劃thread.start()啓動該線程,那麼期望該新Thread中的BMT能夠如所描述的那樣管理它的事務是合理的以上?

數據源是通過JNDI檢索。使用XA或非XA不會影響結果。

我無法發佈的代碼。

As a reference, here is the link to the Spring 3.1 docs on transaction in chapter 11.

新增2013年10月4日 - 我看到Spring使用JtaTransactionManagerBeanDefinitionParser基於感知到容器上構建所需的JtaTransactionManager。當這個被使用,JTA事務管理器將設置到自己在afterPropertiesSet的UserTransaction的,事務管理和TransactionSynchronizationRegistry。

看來,我的確還是漏的CMT數據,但是,這是很難察覺/觀察這一點沒有調試器或迫使錯誤不自然,因爲交易通常提交。

看來我的問題是我已經部分繞過了JCA,因此JCA正在使用不同的TransactionManager。

部分答案 - 因爲我已經在CMT和BMT的混合妥善觀看此辦理,我知道這是可能有BMT交易中的一種方法啓動,並承諾在另一個。

問題仍然是:如果春天有個CMT管理的servlet產生一個新的線程,並有計劃thread.start(開始線程),它是合理的期望,新的線程中的BMT將能夠如上所述管理其交易?

回答

1

從JTA 1.1規範(http://download.oracle.com/otn-pub/jcp/jta-1.1-spec-oth-JSpec/jta-1_1-spec.pdf)第3.1節可以明顯看出,事務綁定到線程。這由TransactionManager管理。如果線程是創建事務的線程,則應該能夠期望線程能夠在事務上下文中執行操作。

請注意,對嵌套事務的支持是可選的,如JTA規範的相同部分中所引用的。

我遇到的實際問題是,託管數據源使用事務管理器的不同實例,而不是我們在應用程序中作爲bean使用的實例。更改應用程序代碼以對容器提供的TransactionManager執行JNDI查找,可以使託管數據源參與與應用程序相同的事務。