使用SSH2框架开发了一套业务应用网站,在开发环境下运行正常,没暴露任何问题,这几天安排测试,安装了一台服务器,结果,四人测试一会就没响应了,由正常进入死锁状态有时时间长一点,有时时间短些,没有规律,也没发现具体引起错误的业务操作,故障发生的很偶然,很随机,顿时感到茫然,束手无措无措。
经过长时间反复改变测试方法,多人多次到单人单业务,逐个尝试,最后发现的规律是,某个报表连续点击保存按钮7次后,第八次系统必定进入死锁状态,这时候tomcat工作是正常的,就是所有与数据操作有关的动作一律死锁,服务器端无任何输出错误信息和日志记录。
分析这个模块的代码发现,本模块保存报表的action中,在update前,先调用getSession().createQuery(queryString);获得报表的初始内容,而其它模块此功能使用的是getHibernateTemplate().find()方法,通过搜索资料才发现,getSession()得到的session不能自动关闭数据库连接,多次连接导致数据库连接池溢出,所有与数据库操作有关的动作都进入死锁状态,也不知道多长时间能恢复正常,最好的办法就是尽量不使用getSession(),用getHibernateTemplate().find()代替。
如果一定要使用getSession()这种原生态的session(这样获得的原生态session比getHibernateTemplate().find()功能多,比如分页查询),一定要手工调用close方法关闭。或者使用回调机制,让spring帮你关闭,代码如下:
return this.getHibernateTemplate().executeFind(new HibernateCallback(){
public List doInHibernate(Session session) throws HibernateException, SQLException {
Query query=session.createQuery(hqlString);
query.setFirstResult(startRow1);
query.setMaxResults(pageSize1);
return query.list();
}