2014-09-23 72 views
1

我對Hibernate非常新穎,在我的頭腦中有這個新手問題,我無法在網上找到任何明確答案。休眠會話和併發性

在我的多線程應用程序中,我想使用Hibernate來實現數據持久性。本質上應用程序是基於事件的,意味着新事件會產生新的線程來處理傳入的數據。從我的在線Getting Started教程中,我實現了Hibernate會話工廠,它將創建單個會話對象,並將返回HibernateUtil.getSessionFactory().getCurrentSession()。從相同的教程中,我用這個廠如下:

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
session.beginTransaction(); 

/* 
    do smth here 
*/ 

session.getTransaction().commit(); 

我要說明的是,因爲有在不同的線程共享只有一個會話對象將這段代碼的並行工作?

比如我不清楚將如何處理情況下,當第一個線程啓動的事務,那麼第二個線程開始交易,那麼第一個線程試圖提交事務,它會犯哪些事務?由於我將HQL或Criteroins應用於Session對象,它是否知道應該將其應用於哪個事務?

+0

這是相當一段時間以前,我讀了休眠手冊。但在那時,它不是線程安全的。所以這必須再次檢查。 – user743414 2014-09-23 08:07:04

回答

1

無需擔心跨多個線程共享會話。默認情況下,SessionFactory將綁定每個線程中的Session三種可能的配置。這裏是Hibernate 4文檔的摘錄:

但是,從版本3.1開始,SessionFactory.getCurrentSession()的處理現在是可插入的。爲此,已經添加了一個新的擴展接口org.hibernate.context.spi.CurrentSessionContext和一個新的配置參數hibernate.current_session_context_class,以允許定義當前會話的範圍和上下文的可插入性。

...

外的開箱,Hibernate內置了此接口的三種實現:

org.hibernate.context.internal.JTASessionContext:當前會話通過跟蹤和作用域JTA交易。這裏的處理過程與之前的僅適用於JTA的方法完全相同。有關詳細信息,請參閱Javadocs。

org.hibernate.context.internal.ThreadLocalSessionContext:當前會話通過當前執行的線程來跟蹤。有關詳細信息,請參閱Javadocs。

org.hibernate.context.internal.ManagedSessionContext:當前會話通過當前執行的線程來跟蹤。但是,您有責任使用此類上的靜態方法綁定和取消綁定Session實例:它不會打開,刷新或關閉會話。

+0

請參閱我的評論http://stackoverflow.com/questions/25989277/hibernate-session-and-concurrency/25991097#comment40700703_25990200你能確認我的理解是否正確嗎? – AlexKey 2014-09-23 09:22:45

+1

不完全。每個線程有一個會話。 'getCurrentSession()'爲相同的請求線程返回相同的會話對象。在不同的請求線程中,它創建(一次)並返回不同的會話對象。 – dcernahoschi 2014-09-23 09:30:59

+0

因此,只要在一個線程內,我不會做兩個重疊交易,我應該安全嗎?如果我需要在一個線程中執行兩個重疊事務,是否值得創建新會話? – AlexKey 2014-09-23 09:42:17

0

的SessionFactory - 它共享單個對象整體application.It是線程。

會議 - 它會爲每個應用程序請求創建。它確實與任何其他對象共享,它不是線程安全的。

+0

因此,每次我調用'SessionFactory#getCurrentSession'時,它實際上都會創建具有相同參數的新對象?然後,只要我爲每個事件使用一個會話(如上面的代碼中所示),那麼我就可以爲完全併發應用程序做好準備,無需進一步設置或更改。我理解正確嗎? – AlexKey 2014-09-23 08:42:29