最近一个项目,用的是spring MVC和hibernate3.1的数据采集任务功能, 总是执行几次后页面停留在数据刷新状态, 查询无法进行, 深入了解后, 原来是程序中DAO层的save和update方法出了问题,
@Transactional
public void save(E entity) {
//this.getSession().save(entity); 项目中原来的写法.
this.getHibernateTemplate().save(entity);
}
原来的写法 this.getSession(); 在多线程的情况下, session没有进行自动释放, 连续的多个getSession()操作,spring无法自动关闭这些session, 即使对save进行try catch也不会有任务错误提示.
this.getHibernateTemplate().save 实际使用的应该是this.getHibernateTemplate().getSessionFactory().getCurrentSession().save()方法
this.getHibernateTemplate().getSessionFactory().getCurrentSession()
从spring管理的sessionFactory中创建一个绑定线程的session。Spring会根据该线程的执行情况来自动判断是关闭session还是延迟关闭。不用手动管理实务,一个线程开启和关闭一次session且性能应该是最好的。
若使用 HibernateDaoSupport 提供的 getSession()方法,正常情况下是不用手动管理的, 不过多线程下, 需要在session操作完毕后执行一下 releaseSession(session) 方法, 程序包含多线程情况下 不推荐使用这种方式.
如果需要获取session, 建议使用 this.getHibernateTemplate().getSessionFactory().getCurrentSession(); SessionFactory是线程安全的.
补充:在多线程执行的情况下
使用: this.getHibernateTemplate().getSessionFactory().getCurrentSession() 获取session时报错,
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
需要使用 HibernateDaoSupport 提供的 getSession()方法, 并手动在方法结尾 releaseSession(session) 一下.