2010-10-07 20 views
5

我有一個使用Spring 2.5的應用程序和Hibernate 3如何建立兩個Web應用程序和使用Spring的事務中批處理作業和Hibernate

有與表示層,一個servive層和Web應用程序DAO層,以及一些Quartz作業共享相同的服務和DAO層。

交易與@Transactional註釋不同層被初始化,就像這樣:

alt text

這導致我在這裏我所描述的問題:Controlling inner transaction settings from outer transaction with Spring 2.5

我讀了一些關於如何設置將Spring和Hibernate連接起來。看起來推薦的方法是初始化服務層中的事務。

我不喜歡的是大多數事務的存在僅僅是因爲他們需要休眠才能正常工作。

當我真的需要一個調用多個服務方法的工作事務時,似乎我沒有選擇從作業中初始化事務。因此,從DAO移動@Transactional註釋到服務似乎沒有任何區別。

您會如何建議設置此類應用程序的交易?

+0

很好的問題,我是要問它自己:) – willcodejavaforfood 2010-10-28 13:06:05

+0

有問題幫助並不像喜歡幫助答案,但它仍然很好聽; o) – Damien 2010-10-28 15:16:51

回答

5

我讀了一些關於如何設置事務以將Spring和Hibernate連接在一起的事務。看起來推薦的方法是初始化服務層中的事務。

當然。事務的劃分應該在服務層級別上進行,而不是在DAO層級別:

  • 工作的單位是服務,而不是你想要如果需要交易跨越多個DAO的DAO

我不喜歡的是,大多數的交易,因爲他們所需要的休眠正常工作,只存在。

您應該詳細說明這一部分,因爲事務不是Hibernate特有的。

當我真的需要一個調用多個服務方法的工作事務時,似乎我沒有選擇從作業中初始化事務。

如果要調用多個服務從作業層發起的事務中,與REQUIRED語義(默認)交易申報您的服務和依賴於Spring事務傳播(適用,除非你需要一個遠程調用;在這種情況下,使用EJB)。

因此,將@OnTransactional註釋從DAO移動到服務似乎沒有任何區別。

確實有所作爲,你需要從工作層時運行批不使事情變得不同發起交易的事實。

我熱烈推薦閱讀Chapter 9. Transaction management


(......)我的主要問題來自於休眠。對不起,如果我不清楚。

沒問題。只是當問題模糊時,你經常會得到一個模糊的答案:)

從hibernate文檔:「數據庫事務從來不是可選的,這就是爲什麼開發人員將DAO方法交易到我的項目上的原因。

很抱歉,但上面的語句只是說「與數據庫通信具有發生交易」,僅此而已,並決定從哪裏開始交易,在您的自由裁量權留給(通常是服務層)。如果您在DAO級別執行此操作,那麼MySuperService調用DaoFooDaoBarDaoBar會失敗怎麼辦?在這種情況下,您可能想要回滾所有更改,而不僅僅是在DaoBar中執行的更改。因此需要控制工作單元開始的交易。

恕我直言,開發者需要一些指導。

這是否意味着我的所有服務都應該是事務性的?即使我剛剛讀取數據,例如?

首先,我建議閱讀Non-transactional data access and the auto-commit mode(的Sessions and transactions小弟)澄清有關「只讀交易」事情。閱讀整個頁面是值得的,但讓我舉這個特定部分:

許多應用程序開發人員認爲他們 可以談論到數據庫的 交易之外。這顯然不是 可能; 沒有SQL語句可以發送 到數據庫以外的數據庫 事務。術語非事務性 數據訪問意味着沒有 明確的事務邊界,沒有 系統事務,並且數據訪問的行爲是 自動提交模式的行爲。這並不意味着沒有 物理數據庫事務涉及 。

一旦你完成上述鏈接,下一個建議的閱讀將是@Transactional read-only flag pitfalls。下面是相關的部分:

(...)底線是,當您使用基於ORM的框架 時, 只讀標誌是無用的,而在 中大多數情況下都會被忽略。但是,如果你 仍然堅持使用它,總是設置 傳播模式,以支撐物,如清單9所示 ,所以沒有交易 啓動:使用

清單9.只讀和SUPPORTS傳播模式選擇 操作

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS) 
public TradeData getTrade(long tradeId) throws Exception { 
    return em.find(TradeData.class, tradeId); 
} 

更重要的是,只是避免做讀操作時,使用 @Transactional註釋完全 ,如圖所示 清單10:

清單10.刪除@Transactional標註爲選擇 操作

public TradeData getTrade(long tradeId) throws Exception { 
    return em.find(TradeData.class, tradeId); 
} 
+0

感謝您的解釋帕斯卡爾。我明顯看過第9章,但是我的主要問題來自Hibernate。對不起,如果我不清楚。從休眠文檔:「數據庫事務決不是可選的,所有與數據庫的通信都必須發生在事務內部。」這就是爲什麼開發人員將DAO方法交易到我的項目上的原因。這是否意味着我的所有服務都應該是交易性的?即使我剛剛讀取數據,例如? – Damien 2010-10-07 18:24:03

+0

@帕斯卡感謝您的時間和澄清。 – Damien 2010-10-07 22:21:04

+0

@Damien不客氣,很高興你發現它很有用 – 2010-10-08 04:13:58

相關問題