Could not obtain transaction-synchronized Session for current thread原因及解決方案
在開發中,碰到到了Could not obtain transaction-synchronized Session for current thread異常,因此特意記錄下。
一、問題的產生
在使用Hibernate時碰到了如下異常:
檢查了程式碼發現是程式碼中用sessionFactory.getCurrentSession()這樣獲取session,導致拋了這異常。
二、問題的解決過程
(1)先看下Hibernate相關的配置
Hibernate版本是4.3.7,這裡先說明一下。Hibernate相關配置如下:
通過這個配置,並沒發現什麼不妥的地方。
注意:
hibernate.current_session_context_class = thread
(2)從網上找答案
在網上找到一篇文章,很好的解釋了為什麼會報這個錯。連結為:http://blog.csdn.net/honghailiang888/article/details/53423941
這文章裡面有一段話提醒了我。文章關鍵知識截圖如下
重點知識:
-
- (1)必須要將使用了sessionFactory.getCurrentSession()獲取session的程式碼所在的方法加入到事務管理器中;否則獲取不到session了。
- (2)sessionFactory.getCurrentSession()是要基於事務的,才能實現session生命週期的管理。所以我們查詢方法上用個只讀事務就ok了。
瞭解到這個知識點後,我去看了下公司的專案程式碼,發現沒有配事務切面,也沒有用註解事務。 所以我當時寫的程式碼所在的方法是沒有加入到事務管理器中的;因此也就報了這個異常。
(3)解決問題
由於service方法沒有加入到事務管理器中,因此我修改了些配置檔案。使用的不是宣告式事務,是用的註解事務,這樣方便點。配置如下:
在我剛剛報錯的Service方法中,加上了註解@Transactional(readOnly=true)
結果: 執行程式,一切正常
三、小結
在之前的開發中,一直沒碰到這個問題;突然在公司的一個小專案中碰到了這問題。回想之前的程式碼,service層的方法當時都是用事務切面切中的,所以不會報這個錯。而現在這個專案,既沒有配事務切面,也沒用註解事務;所以才報這個錯。
在後續的開發中,記住:使用了sessionFactory.getCurrentSession()獲取session時,需要事務的支援;也就是說這段程式碼所在的方法要麼被事務切面切中,要麼方法上面用了註解事務。