问题描述:Hibernate使用时发现了一个问题,就是当请求超过20次的时候tomcat就会卡死,tomcat进程没有挂掉,堆内存也没用溢出,经检查是卡在查询这一块。
应用程序采用struts2 + spring2 + hibernate3架构
连接池配置使用的是c3p0,最大池大小为20, 很显然是连接池耗尽导致的。增加连接池大小只是饮鸩止渴,总还有耗尽的时候。
最开始Dao层代码
public class RiskMapDao extends BaseDaoSupport{
public Pager<RiskMapDto> getRatinglist(String riskname) {
Pager<RiskMapDto> pager = new Pager<RiskMapDto>();
Session session = getSession();
try {
StringBuffer hql = new StringBuffer("select t.province, t.city, t.county, t.riskname from map_data t where 1=1 ");
if(riskname != null && riskname != ""){
hql.append(" and t.riskname ='" + riskname +"'");
}
System.out.println("-------------"+hql+"-------------");
Query query =session.createSQLQuery(hql.toString()) ;
pager.setList(query.list());
session.close();
} catch (HibernateException e) {
e.printStackTrace();
}
return pager;
}
}
我尝试在获得list之后,使用getSession().close()关闭,依旧没有效果。查阅Spring API发现geSession()是 org.springframework.orm.hibernate3.support.HibernateDaoSupport 中的一个方法,它可以从当前事务或者一个新的事务获得一个hibernate session。我写的代码中数据库连接并没有被真正的关闭。
解决方案一:
在finally里面清空session,无论是否抛出异常,finally代码块总是会被执行。finally代码块主要用来释放资源。
public class RiskMapDao extends BaseDaoSupport{
public Pager<RiskMapDto> getRatinglist(String riskname) {
Pager<RiskMapDto> pager = new Pager<RiskMapDto>();
Session session = getSession();
try {
StringBuffer hql = new StringBuffer("select t.province, t.city, t.county, t.riskname from map_data t where 1=1 ");
if(riskname != null && riskname != ""){
hql.append(" and t.riskname ='" + riskname +"'");
}
System.out.println("-------------"+hql+"-------------");
Query query =session.createSQLQuery(hql.toString()) ;
pager.setList(query.list());
} catch (HibernateException e) {
e.printStackTrace();
}finally{
session.close();
}
return pager;
}
}
解决方案二:
使用releaseSession(org.hibernate.Session)方法与getSession()配合,如果没有绑定线程,releaseSession关闭由这个DAO的SessionFactory创建的Hibernate Session。
public class RiskMapDao extends BaseDaoSupport{
public Pager<RiskMapDto> getRatinglist(String riskname) {
Pager<RiskMapDto> pager = new Pager<RiskMapDto>();
Session session = getSession();
StringBuffer hql = new StringBuffer("select t.province, t.city, t.county, t.riskname from map_data t where 1=1 ");
if(riskname != null && riskname != ""){
hql.append(" and t.riskname ='" + riskname +"'");
}
System.out.println("-------------"+hql+"-------------");
Query query =session.createSQLQuery(hql.toString()) ;
pager.setList(query.list());
releaseSession(session);
return pager;
}
}