spring 控制hibernate的session何时关闭.

转载 2011年10月18日 14:20:01

 http://blog.csdn.net/dengyin2000/article/details/448341

 

在用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.

note:如果一个service中调用另外一个service,如果另外一个service的事务传播类型是required的话,那么两个service中使用的是同一个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.

Spring 中Hibernate session 打开和关闭总结

session的断开是在org.springframework.orm.hibernate.SessionFactoryUtils中处理的。  如果应用程序使用了OpenSessionInViewF...
  • mafly008
  • mafly008
  • 2013-08-29 19:33:57
  • 5913

Spring和Hibernate整合时对session及事务管理的理解

配置: Spring配置文件中配置了对hibernate的sessionFactory管理以及生命式事务。使用: 事务配置在Service层,在DAO层调用时getSession、getCurre...
  • jiangjiajian2008
  • jiangjiajian2008
  • 2016-06-19 23:59:12
  • 2576

在spring MVC和hibernate项目中如何实现hibernate的session在请求发起时开启数据渲染后自动关闭

对于才接触hibernate的初学者来说可能会遇到的一个问题就是hibernate的session的管理问题,简单举一个列子,假设一个电商网站,我要读取产品信息,用户发起请求后我们后台去数据库查询产品...
  • qq_24172609
  • qq_24172609
  • 2017-06-07 19:15:12
  • 451

hibernate的延迟加载及其与session关闭的矛盾

延迟加载就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载。     那么Hibernate是怎么知道用户在什么时候使用数据了呢?又是如何加载数据呢?     其实很简单,它使用了代理机...
  • WarcraftJimmy
  • WarcraftJimmy
  • 2012-05-04 17:16:14
  • 7126

spring hibernate 单元测试手动开启关闭session

import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hi...
  • yuanyuan05
  • yuanyuan05
  • 2017-11-03 11:01:08
  • 156

spring data jpa session 查询时 session 已经关闭问题

前提:首先我的项目架构,采用的是spring boot + jpa 实现的。因此模型之间的关系就不得不采用 一对多,和多对一等关系来标识。 情景:一对多情况,我一个老师,和 多个学生,因此在...
  • jun522450654
  • jun522450654
  • 2017-06-15 10:20:50
  • 1180

用spring控制hibernate的session何时关闭

在用spring管理hierbernate的事务我们一般都用TransactionProxyFactoryBean去配置我们的Service方法.如.         ...
  • mliu222
  • mliu222
  • 2010-11-21 10:31:00
  • 505

Spring不对Hibernate原方法操作数据库提供连接关闭服务

前几天我把我之前运用Hibernate+struts1.x框架开发的web项目搬到Spring框架上,其中Hibernate和struts都配置到applicationContext.xml文件上,通...
  • c_p_h
  • c_p_h
  • 2017-04-28 21:37:13
  • 688

Hibernate中session的关闭问题

Hibernate中session的关闭问题实现一个修改客户信心的功能,分为两部分:一、点击修改,跳转到后台,然后执行根据id查询客户信息的 操作,并将查询到的客户信息回显到前台。二、前台将修改完的信...
  • u014580622
  • u014580622
  • 2016-09-26 22:49:08
  • 2251
收藏助手
不良信息举报
您举报文章:spring 控制hibernate的session何时关闭.
举报原因:
原因补充:

(最多只允许输入30个字)