Spring如何關閉Hibernate的數據庫鏈接

在使用Spring進行系統開發的時候,數據庫鏈接通常都是配置在Spring的配置文件中,而且由Spring來管理的。在利用Spring + Hibernate進行開發時也是如此。下面是一個簡單的Spring + Hibernate Dao的例子:

 java

程序代碼
public class DaoReal extends HibernateDaoSupport implements Dao {
  public List<User> getAll() {
    return super.getHibernateTemplate().find("from User");
  }
}


  在上面的這個例子中,咱們並無關閉Session,但程序並無任何問題,那是由於Spring已經幫咱們關閉了。那麼再看一個例子:

 數據庫

程序代碼
public class DaoReal extends HibernateDaoSupport implements Dao {
  public List<User> getAll() {
return super.getSession().createQuery("from User").list();
  }
}


  這個例子會不會有問題呢?的確,上面的例子中隱藏了一個問題,數據庫鏈接並無被關閉,在咱們的印象中這件事彷佛應該是Spring的。程序執行後,好像也沒有什麼問題,可是連續執行該語句n次(n<=最大鏈接數,若是沒有指定最大鏈接數,那麼默認爲10次)後,系統處於等待狀態,不會繼續執行了,控制檯上並無輸出任何信息。打開log文件,發現系統拋出java.lang.IllegalStateException: Pool not open的異常,沒法打開鏈接。這說明系統鏈接池中全部的鏈接都在使用中。那麼咱們手動關閉Session後,應該就沒有問題了吧!是這樣嗎?修改咱們的例子,以下:

 ide

程序代碼
public class DaoReal extends HibernateDaoSupport implements Dao {
  public List<User> getAll() {
    Session s = super.getSession();
    try {
      return s.createQuery("from User").list();
    } finally {
      s.close();
    }
  }
}


  執行n遍後依然中止響應。問題出在哪裏呢?其實Spring的Session老是與某個線程綁定的,而這個線程每每就是承載Servlet或Jsp的那個線程,也就是說,它的生命週期scope是request的。在上面的例子中,咱們利用getSession強制得到了Hibernate的Session,這個Session多是當前事務中以前使用過的,或者多是一個新的,並不在當前事務中,Spring只對當前事務中的Session進行關閉。

  要解決這個問題,方法有不少。可使用咱們以前講到過的getHibernateTemplate().find()。也能夠設定HibernateTemplate的AllowCreate爲True,並在finally中關閉Session。也能夠將true做爲參數傳遞到super.getSession(..)方法中取得Session。這裏的true表示容許建立。線程

相關文章
相關標籤/搜索