废话不多说,最近在玩自己写的项目,框架是SSH2,数据库是用c3p0连接的,在给一个简单的查询加上分页之后,诡异的事情发生了:在多点几次查询操作时,后台报错:
数据库连接不上。
org.hibernate.exception.GenericJDBCException: Cannot open connection
。。。。
Caused by: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
。。。。
Caused by: com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@1240739 -- timeout at awaitAvailable()
。。。。
一开始怀疑是c3p0设置问题,在增大<property name="maxPoolSize"><value>20</value></property>值后 从原来的点7次变成点十几次后报异常。从网上找各种资料后并没有结果。最后在检查后台代码是发现了错误:
@Override
@SuppressWarnings("all")
public List<HouseSources> queryHouseSources(HouseSources hs,Pager pager, Map map,String hql){
List<HouseSources> result = null;
try{
//这里使用了session,但是没用关闭,造成连接池溢出
Query query = this.getSession().createQuery(hql);
Iterator it = map.keySet().iterator();
while (it.hasNext())
{
Object key = it.next();
query.setParameter(key.toString(), map.get(key));
}
query.setFirstResult((pager.getPageNo()- 1)*pager.getLimit());
query.setMaxResults(pager.getLimit());
result = query.list();
}catch (Exception e){
e.printStackTrace();
}
return result ;
}
这段代码是参考这里 http://gaogengzhi.iteye.com/blog/266301 的分页查询。
this.getSession().createQuery(hql);
这样的写法,不能自动关闭数据库连接,多次连接会溢出,所以一定要在使用后手动关闭,或者调用回调机制,让spring协助关闭修改后的写法如下:
@Override
@SuppressWarnings("all")
public List<HouseSources> queryHouseSources(HouseSources hs,final Pager pager, final Map map,final String hql){
return (List<HouseSources>) this.getHibernateTemplate().execute(new HibernateCallback(){
@Override
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
// TODO Auto-generated method stub
List<HouseSources> result = null;
try{
Query query = session.createQuery(hql);
Iterator it = map.keySet().iterator();
while (it.hasNext())
{
Object key = it.next();
query.setParameter(key.toString(), map.get(key));
}
query.setFirstResult((pager.getPageNo()- 1)*pager.getLimit());
query.setMaxResults(pager.getLimit());
result = query.list();
}catch (Exception e){
e.printStackTrace();
}
return result ;
}
});
}