2012-05-19 51 views
11

我在Tomcat上對Spring使用Hibernate。我一直在閱讀並重新閱讀關於該主題的經文JBoss wiki page,這很有幫助。但它留下了一些問題。休眠在視圖中打開會話:每個請求的事務?

  1. 爲每個請求啓動事務的想法困擾我。我想我可以限制過濾器到某些控制器 - 也許把需要交易的所有控制器都置於僞「tx」路徑之下。但如果你不知道是否需要交易,使用交易不是一個壞主意嗎?如果我只是在讀取某些請求 - 很可能來自緩存的讀取 - 如果沒有事務處理,我是不是更好?

  2. 我讀過的文章提到他們如何處理服務層的事務,我想用Spring來做這件事。但是,過濾器代碼是什麼樣的?我仍然希望可以在我的視圖中使用會話進行一些延遲加載。

  3. 如果我所要做的只是在我的過濾器中調用sessionFactory.getCurrentSession(),它如何將「釋放」返回會話工廠以供再次使用? (即使在使用事務時,我期望看到一個session.close()或其他東西)。誰在告訴會話工廠該會話可以重用?

  4. 也許這是beginTransaction()呼叫,在請求期間將給定的數據庫連接綁定到給定的會話?否則,會話會根據需要從池中提取數據庫連接,對吧?

感謝您的耐心配合我的所有問題。 (如果你的答案將成爲Spring文檔的一個鏈接,那麼你只會讓我哭泣,你不想那樣,你呢?如果人們不再回答Spring,我會付出真金白銀)

回答

20

您的疑慮是有效的,維基頁面上提供的解決方案過於簡單。事務不應該在Web層進行管理 - 應該在服務層進行處理。

正確的實現將打開一個會話並將其綁定到過濾器中的一個線程。沒有交易開始。會話處於刷新模式從不 - 只讀模式。服務調用會將會話設置爲刷新模式自動啓動/提交事務&。一旦服務方法完成,會話刷新模式將恢復爲從不。

還有一個選項可以在過濾器中不打開會話。每個服務層調用將會打開一個單獨的會話&事務 - 服務調用完成後,會話不會關閉,但會註冊爲延遲關閉。會話將在Web請求處理完成後關閉。

Spring提供OpensessionInViewFilter,其工作方式如上所述。因此,忽略jboss wiki文章並配置OpensessionInViewFilter - 一切都會好起來的。

SessionFactory.getCurrentSession() - 在內部創建會話並將其分配給本地線程。每個請求/線程都有自己的會話。一旦Web請求處理完成,會話將被關閉。在你的代碼中,你只需要使用SessionFactory.getCurrentSession()並且不必關閉它。 jboss wiki頁面上的代碼示例是錯誤的 - 它應該在finally塊中包含SessionFactory.getCurrentSession()。close()。或者他們可能正在使用JTA事務並配置hibernate以結合JTA事務來打開/關閉會話。

+0

我一直從這裏到那裏,然後到那裏,跳過關於這個主題的網絡一週...這是我第一次讀到Spring有一個OpenSessionInView過濾器。謝謝。 – Marvo

+0

男人,只是工作得很漂亮。謝謝! – Marvo

+0

我一直認爲它可以用作交易。但事實上這個交易受到了Spring的@Transactional的限制。感謝您的解釋。 –

0

如果過濾器爲每個請求創建一個會話,這不是問題,因爲會話來自會話池,並且它們將被重用。從操作系統的角度來看,沒有任何反應。

hibernate會話實際上是一個到數據庫服務器的tcp(或套接字/管道)連接。 db conn創建的成本與sql類型非常相關(postgresql在這方面顯然很糟糕,儘管它在任何情況下都非常好)。但這並不意味着什麼,因爲hibernate重用了數據庫連接。

簡單的hibernate過濾器解決方案也會在每個請求的會話上啓動一個新的事務。它是從SQL視圖的事務:它是一個「BEGIN」和「COMMIT」查詢。它總是昂貴的,這應該減少。

恕我直言,一個可能的解決方案是,如果事務僅在當前請求的第一個查詢時啓動。也許春天有一些可用的東西。

+1

我們到達的是使用OpenSessionInView過濾器(參見上文)和Spring @Transactional註釋。到目前爲止,它工作得很好。 – Marvo

+0

@馬爾沃我對此沒有那麼好的經驗。你沒有控制權,究竟發生了什麼,爲什麼。在我的最後一個項目中,我有多個數據庫連接(一些實體將第一個,一些連接到第二個連接)與交叉指向彈簧層,一些進程來自Quartz啓動,一些來自Web。情況很複雜,主要的問題是,在基於註釋或/和AOP的事情中,您非常需要控制權來檢查,失敗或問題在哪裏。它只是起作用或不起作用,但你看不到它們。在清晰的程序環境中,這是微不足道的。 – peterh