用spring控制hibernate的session何时关闭

来源:互联网 发布:淘宝发顺丰多少钱 编辑:程序博客网 时间:2024/05/16 12:18

在用spring管理hierbernate的事务我们一般都用TransactionProxyFactoryBean去配置我们的Service方法.

如.

<bean id="baseTxProxy" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
         <property name="transactionManager"><ref bean="transactionManager"/></property>
         <property name="transactionAttributes">
             <props>
     <prop key="*">PROPAGATION_REQUIRED</prop>
     <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>  
     <prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>         
     <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>     
             </props>
         </property>
     </bean>

<!-- <bean id="userManager" parent="baseTxProxy">
         <property name="target">
             <bean class="com.javaeye.user.impl.hibernate.UserManagerImpl" autowire="byName">
                 <property name="cacheQueries"><value>true</value></property>
             </bean>
         </property>
     </bean>
-->       

<bean id="userService" parent="baseTxProxy">
   <property name="target">
    <bean class="com.dengyin.report.service.impl.UserServiceImpl" autowire="byName"/>
   </property>
</bean>

<bean id="dailyReportService" parent="baseTxProxy">
   <property name="target">
    <bean class="com.dengyin.report.service.impl.DailyReportServiceImpl" autowire="byName"/>
   </property>
</bean>

 

我们可以想得到TransactionProxyFactoryBean是使用aop在Service方法之前open 一个session, begin Trans.在Service结束之后Commit Trans, close session.

但是我们使用spring的OpenSessionInViewFilter的时候就不能在Service方法后close session了. 应该是在Render page之后再关闭session的.所以我跟踪了spring的代码. 最后发现了spring是怎样做的.

    HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
    if (txObject.getSessionHolder() == null) {
     Interceptor entityInterceptor = getEntityInterceptor();
     Session newSession = (entityInterceptor != null ?
       getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());
     if (logger.isDebugEnabled()) {
      logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
     }
     txObject.setSessionHolder(new SessionHolder(newSession), true);
    }

    txObject.getSessionHolder().setSynchronizedWithTransaction(true);
    session = txObject.getSessionHolder().getSession();

这段代码是在进行Service之前的. 如果当前thread没有session的话就执行txObject.setSessionHolder(new SessionHolder(newSession), true);注意这里set了一个true值. 我们来看看txObject是一个什么东西.

private static class HibernateTransactionObject extends JdbcTransactionObjectSupport {

   private SessionHolder sessionHolder;

   private boolean newSessionHolder;

   public void setSessionHolder(SessionHolder sessionHolder, boolean newSessionHolder) {
    this.sessionHolder = sessionHolder;
    this.newSessionHolder = newSessionHolder;
   }

   public SessionHolder getSessionHolder() {
    return sessionHolder;
   }

   public boolean isNewSessionHolder() {
    return newSessionHolder;
   }

   public boolean hasTransaction() {
    return (this.sessionHolder != null && this.sessionHolder.getTransaction() != null);
   }

   public void setRollbackOnly() {
    getSessionHolder().setRollbackOnly();
    if (getConnectionHolder() != null) {
     getConnectionHolder().setRollbackOnly();
    }
   }

   public boolean isRollbackOnly() {
    return getSessionHolder().isRollbackOnly() ||
      (getConnectionHolder() != null && getConnectionHolder().isRollbackOnly());
   }
}

我们看看Service方法之后spring怎样close session的.

   Session session = txObject.getSessionHolder().getSession();
   if (txObject.isNewSessionHolder()) {
    if (logger.isDebugEnabled()) {
     logger.debug("Closing Hibernate Session [" + session + "] after transaction");
    }
    SessionFactoryUtils.releaseSession(session, getSessionFactory());
   }
   else {
    if (logger.isDebugEnabled()) {
     logger.debug("Not closing pre-bound Hibernate Session [" + session + "] after transaction");
    }
    if (txObject.getSessionHolder().getPreviousFlushMode() != null) {
     session.setFlushMode(txObject.getSessionHolder().getPreviousFlushMode());
    }
   }
   txObject.getSessionHolder().clear();

当txObject.isNewSessionHolder()的时候才会close   session.

 

总结:

所以当Service方法之间没有存在的session时spring会开一session,然后结束的时候close session.

当Service方法之间有存在的session的话,Service方法结束时并没有关闭   session.

原创粉丝点击