本博客是本身在學習和工做途中的積累與總結,歡迎你們轉載,轉載時請註明出處,請尊重他人努力成果,謝謝。
1. 當有連個sessionFactory時,容易產生獲取不到session的狀況
緣由: 進入事務@Service標註的業務類的業務方法後,當進行數據庫操做時,會經過sessonFactory.getCurrentSession();方法獲取,原理,當本地線程中不存在session時,會調用openSession建立一個並綁定到本地線程中,而後
調用,注意:這裏的建立是當前事務該類中事務所綁定的sessionFactory的session,因此在同一方法中的後N個sessionFactory獲取session時,只要他們的sessionFactory與當前事務所配置的sessionFactory不是同一個,會報獲取不到session的異常,由於該session獲取不到。或者更詳細地說,因爲spring維護一個ThreadLocal<Thread,Map<Object,Object>>來解決線程安全問題,那麼,以當前線程做爲key值,取到存有當前線程中的所需的鍵值對map,而其中就擁有sessionFactory和SessionHolder的鍵值對,而key值SessionFactory對象即爲當前事務的sessionFactory,因此若是是其餘sessionFactory去獲取的話,會致使拿取出來的值爲null。
補充一下:sessionHolder就是拿去session的對象哦 ,在CurrentSessionContext的接口實現類中的currentSession方法中。
解決辦法:
1. 經常使用的sessionFactory的事務管理可使用註解配置 ,不經常使用的可使用spring的聲明式事務管理配置(能夠配置多個),這樣就互不相干,不會出現拿不到sesson的問題
2. 後續的sessionFactory須要本身手動的調用openSession,來進行操做,而且須要手動關閉。
補充一下,使用懶加載也會致使拿不到session,但於此問題無關,能夠配置open session in view,但會極其損耗應用性能。
源碼解析:
此中,resources.get()方法是爲了拿去當前線程中的全部鍵值對,而sessionFactory的實例對象在此map中爲鍵,值爲SessionHolder實例對象(org.springframework.orm.hibernate4.SessionHolder),
而惟有事物中配置的sessionFactory才能經過map取出value(SessionHolder對象),因此返回null。
接下來:
返回null
因爲value=null,因此拋一個異常嘍