Spring中使用getSession()與通過HibernateTemplate進行數據操作的差別
在 Spring+Hibernate的集成環境裏,如果DAO直接使用HibernateDaoSupport的getSession()方法獲取 session進行數據操作而沒有顯式地關閉該session,那麼程序表現爲:每個session會打開一個connection,並且 connection會一直保持(因爲沒有顯式地close).如果程序使用了c3p0連接池,則因爲c3p0連接池默認最大連接數是15,程序會表現爲當打開第15個連接時,程序處於停滯狀態,等待從連接池獲取新的連接.
在同樣條件下,使用HibernateTemplate進行數據操作,就沒有連接數持續增長的情況,程序結束時連接數歸零.這印證了spring文檔上所說:HibernateTemplate會對session進行了管理,能夠確保Session實例的正確打開和關閉.
需要注意的是:在Spring環境裏,即使我們使用Hibernate原生的API,比如這裏所說的使用HibernateDaoSupport的getSession()方法得到Session進行數據操作(而不是使用Spring自己提供的API,比如HibernateTemplate),這些操作也依然會被納入spring管理的事務中去.原因是通過getSession()方法得到Session是一個綁定到當前事務上的session.此處可參考:http://www.javaeye.com/topic/110801.這就是爲什麼Spring文檔中提到的:You can implement DAOs based on the plain Hibernate 3 API, while still being able to participate in Spring-managed transactions.
如果程序使用了OpenSessionInViewFilter或者OpenSessionInViewInterceptor那將是另外一種情形了.
簡單總結: HibernateDaoSupport的getSession()得到的Session會參與Spring管理的事務中,但是不能自動的關閉.
HibernateTemplate 除能參與到 Spring管理的事務中,還 能夠確保Session實例的正確打開和關閉.