这段时间遇到一个问题,接收的项目Dao继承的是 HibernateDaoSupport 且没有加上事务 在进行后期测试的时间发现web服务器内存爆掉了,后来检测了一下session的开启数,发现有很多session没有关掉,因为这个问题就到网上查了资料,网上大部分的解决如下
1.重写 HibernateDaoSupport用ThreadLocal保存Session列表并编写一个配套的过滤器来显式关闭Session, 并在关闭之前尝试提交事务. 下面是重写的 HibernateDaoSupport 代码:
package org.springframework.orm.hibernate3.support;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.support.DaoSupport;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
/**
* 修改后的避免连接泄漏的 HibernateDaoSupport, 多连接版本, 不保证跨DAO的事务.
*
* @author 刘长炯
* Date: 2009-3-11
*/
publicabstractclass HibernateDaoSupport extends DaoSupport {
/** 使用 ThreadLocal 保存打开的 Session 列表 */
privatestaticfinal ThreadLocal< List<Session> > sessions = new ThreadLocal< List<Session> >();
/**
* 获取Hibernate连接.
* @return
*/
publicstatic List<Session> getSessionList() {
//1. 先看看是否有了List get()
List list = sessions.get();
// 2. 没有的话从创建一个, put()
if(list == null) {
list = new ArrayList();
sessions.set(list);
}
// 3. 返回 Session
return list;
}
/**
* 关闭当前线程中未正常释放的 Session.
*/
publicstaticvoid closeSessionList() {
// 1. 先看看是否有了List get()
List<Session> list = sessions.get();
// 2. 有的话就直接关闭
if(list != null) {
System.out.println(SimpleDateFormat.getDateTimeInstance().format(new java.util.Date()) +
" -------- 即将释放未正常关闭的 Session");
for(Session session : list) {
System.out.println("正在关闭 session =" + session.hashCode());
// ! 关闭前事务提交
if(session.isOpen()) {
try {
session.getTransaction().commit();
} catch(Exception ex) {
try {
session.getTransaction().rollback();
} catch (HibernateException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
try {
session.close();
} catch(Exception ex) {
}
}
//releaseSession(session); // 无法调用
}
sessions.remove();
}
}
private HibernateTemplate hibernateTemplate;
/**
* Set the Hibernate SessionFactory to be used by this DAO.
* Will automatically create a HibernateTemplate for the given SessionFactory.
* @see #createHibernateTemplate
* @see #setHibernateTemplate
*/
publicfinalvoid setSessionFactory(SessionFactory sessionFactory) {
if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) {
this.hibernateTemplate = createHibernateTemplate(sessionFactory);
}
}
/**
* Create a HibernateTemplate for the given SessionFactory.
* Only invoked if populating the DAO with a SessionFactory reference!
* <p>Can be overridden in subclasses to provide a HibernateTemplate instance
* with different configuration, or a custom HibernateTemplate subclass.
* @param sessionFactory the Hibernate SessionFactory to create a HibernateTemplate for
* @return the new HibernateTemplate instance
* @see #setSessionFactory
*/
protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {
return