本人在項目中,實現分頁查詢時,遇到了這個問題,當多次翻頁後,頁面請求被掛起。項目使用spring MVC+hibernate。刷新頁面沒有反應,從新登陸同意不起作用,只有重啓tomcat才能解決。經過1個多小時的調試,也沒能找到問題所在,但發現了一個規律,就是每次出現頁面卡死(即請求被掛起)都是在進行了固定次數(5)的翻頁以後。由於程序未報任何異常,一直頭疼中,但是突然想到了連接池,因爲我的連接池最多連接數爲10。想到了這裏,感覺似乎抓到了問題的關鍵所在。然後百度了一下,果然就是這個原因。
問題代碼如下:
protected <T> List<T> queryByPage(String sql,int page,int pageSize){
Session session = getSession();
Query query = session.createQuery(sql);
//(page-1)*pageSize:將頁碼轉化爲實際數據庫查詢起始位置
query.setFirstResult((page-1)*pageSize);
query.setMaxResults(pageSize);
List<T> list = query.list();
return list;
}
protected String count(String sql){
Session session = getSession();
Query query = session.createQuery(sql);
String count = query.list().get(0).toString();
return count;
}
這裏沒有對session進行關閉和釋放,因爲我的代碼每次都要獲取分頁數據和總數,所以剛好5次以後,連接池被耗盡。在return 語句前面加上releaseSession(session);問題解決。
另外還有一種方式可以解決該問題:爲查詢方法也使用事務(這裏我使用的是註解方式:在方法前面加上@Transactional(propagation=Propagation.NEVER)),使用事務後spring就會爲當前線程綁定session,在執行完本次請求之後,spring會自動釋放session。代碼應該修改爲這樣:
protected <T> List<T> queryByPage(String sql,int page,int pageSize){
// Session session = getSession();
Session session = getSessionFactory().getCurrentSession();
Query query = session.createQuery(sql);
//(page-1)*pageSize:將頁碼轉化爲實際數據庫查詢起始位置
query.setFirstResult((page-1)*pageSize);
query.setMaxResults(pageSize);
List<T> list = query.list();
// releaseSession(session);
return list;
}
這裏的session採用getSessionFactory().getCurrentSession();獲得。問題得到解決。