首页 » my » 正文

Spring+Hibernate的项目session管理的记录

公司一个运营的项目,使用spring+hibernate来进行开发架构,近段时间以来,经常出现无法访问的情况 ,查看服务器上的信息,发现在数据库的连接一直在sleep,也就是说数据库的连接一起没有有释放,导致平台无法获取新的连接,无法连接数据库。

一般来说,使用spring的AOP来进行事务管理的连接不应该出现这种情况的,检查源代码,发现代码中大量的使用this.getSession()方法来获取数据库连接进行查询。

查看相关的文档:

HibernateDaoSupport 代码里面的原始说明文档指出直接调用getSession() 方法必须用配套的releaseSession(Session session) 来释放连接。

 

/** 

         * Obtain a Hibernate Session, either from the current transaction or 

         * a new one. The latter is only allowed if the 

         * {@link org.springframework.orm.hibernate3.HibernateTemplate#setAllowCreate "allowCreate"} 

         * setting of this bean's {@link #setHibernateTemplate HibernateTemplate} is "true". 

         * <p><b> Note that this is not meant to be invoked from HibernateTemplate code 

         * but rather just in plain Hibernate code. </b> Either rely on a thread – bound 

         * Session or use it in combination with {@link #releaseSession} . 

         * <p> In general, it is recommended to use HibernateTemplate, either with 

         * the provided convenience operations or with a custom HibernateCallback 

         * that provides you with a Session to work on. HibernateTemplate will care 

         * for all resource management and for proper exception conversion. 

         * @return the Hibernate Session 

         * @throws DataAccessResourceFailureException if the Session couldn't be created 

         * @throws IllegalStateException if no thread – bound Session found and allowCreate=false 

         * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession(SessionFactory, boolean) 

         */ 

       protected final Session getSession() 

           throws DataAccessResourceFailureException, IllegalStateException { 

              return getSession( this . hibernateTemplate .isAllowCreate()); 

       }  

 

       /** 

         * Close the given Hibernate Session, created via this DAO's SessionFactory, 

         * if it isn't bound to the thread (i.e. isn't a transactional Session). 

         * <p> Typically used in plain Hibernate code, in combination with 

         * {@link #getSession} and {@link #convertHibernateAccessException} . 

         * @param session the Session to close 

         * @see org.springframework.orm.hibernate3.SessionFactoryUtils#releaseSession 

         */ 

       protected final void releaseSession(Session session) { 

              SessionFactoryUtils.releaseSession (session, getSessionFactory()); 

       } 

spring的文档中指出:

   Spring的Session是一个thread-bound Session ,就是说它是和某个线程绑定的,而这个线程往往就是承载Servlet/Jsp的那个线程,实际意思就是其生命周期scope是request/response的。所以和Servlet的context无关。

   强制通过getSession()获得的Hibernate Session, 这个session可能是当前事务中之前打开的用过的那个Session,或者可能是一个新的,如果你需要必须是新的,那么通过你引用的那个HibernateTemplate中 的allowCreate为true!然后必须配套使用releaseSession(session)。

  如果必须需要getSession(),可以使用getHibernateTemplate().getSessionFactory().openSession()来获取,这样获取的session是受spring的事务管理的。