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何时关闭.相关推荐

  1. (继续搬)struts日期格式的转换以及hibernate中session的关闭在xml中的配置

    1.struts日期格式的转换package cn.sxx.utils;import java.text.ParseException; import java.text.SimpleDateForm ...

  2. hibernate 管理 Session(单独使用session,非spring)

    hibernate 管理 Session(单独使用session,非spring) Hibernate 自身提供了三种管理 Session 对象的方法 Session 对象的生命周期与本地线程绑定 S ...

  3. Spring boot 解决 hibernate no session异常

    Spring boot 解决 hibernate no session异常 参考文章: (1)Spring boot 解决 hibernate no session异常 (2)https://www. ...

  4. 在将hibernate的session托管给spring过程中的问题

    No CurrentSessionContext configured ------Hibernate 出现上面的错误提示:如果是只有hibernate的配置则: org.hibernate.Hibe ...

  5. 整合Struts2、Spring、Hibernate构建J2EE应用

    [论文摘要] J2EE即是以Java 2平台为基础的体系结构,又是一组旨在简化企业解决方案的开发.部署.运行.维护等相关复杂问题的技术规范与指南.Struts2.Spring.Hibernate是当今 ...

  6. spring和hibernate的整合

    阅读目录 一.概述 二.整合步骤 1.大致步骤 2.具体分析 一.概述 Spring整合Hibernate有什么好处? 1.由IOC容器来管理Hibernate的SessionFactory 2.让H ...

  7. ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存

    ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate  : Hibernate是一个持久层框架,经常访问物理数据库 ...

  8. Spring+SpringMVC+Hibernate整合操作数据库 概述

    概述 Hibernate是一款优秀的ORM框架,能够连接并操作数据库,包括保存和修改数据.Spring MVC是Java的web框架,能够将Hibernate集成进去,完成数据的CRUD.Hibern ...

  9. .netcore 如何获取系统中所有session_集群化部署,Spring Security 要如何处理 session 共享?

    前面和大家聊了 Spring Security 如何像 QQ 一样,自动踢掉已登录用户(Spring Boot + Vue 前后端分离项目,如何踢掉已登录用户?),但是前面我们是基于单体应用的,如果我 ...

最新文章

  1. [转]VS2010安装说明及所有安装出错的解决办法
  2. 3-1 Point类的构造函数_JAVA
  3. AAAI21最佳论文Informer:效果远超Transformer的长序列预测神器???
  4. Python基础——PyCharm版本——第三章、数据类型和变量(超详细)
  5. vue中的数据单向绑定,判断,循环,函数
  6. 魔方财务对接码支付插件
  7. python学习(6)--logging打印日志
  8. 光储充一体化充电站_忙时给车充电 闲时上网供电 多能电动车充电站在乐清投用...
  9. 力扣-61 旋转链表
  10. 20 个实例玩转 Java 8 Stream,写的太好了!
  11. java实现行政区域划分_java解析中国行政区域并在页面显示实现动态逐级筛选
  12. 从2D图像生成3D模型,基于Im2Avatar
  13. [2022-04-27] refresh PDB
  14. 如何在图片上添加边框和文字
  15. Scrapy 2.6 Requests and Responses 请求和响应使用指南
  16. 忘记mysql的root密码啷个办
  17. mac安装golang,编写第一个go程序
  18. 14宽的键槽深度多少_平键和键槽标准尺寸规格表.doc
  19. 问题-某个程序改了ICO图标后编译后还是显示老图标?
  20. 2019初创企业投融资服务平台都有哪些?

热门文章

  1. mybatis应用(二)注解的实现
  2. vim树形目录NERDTree
  3. 【Linux】一步一步学Linux——exec命令(208)
  4. 【Linux】一步一步学Linux——wc命令(52)
  5. 【Linux系统编程】进程间通信--共享内存
  6. 两个多精度十进制数加法程序设计_初中数学之有理数的加减,学会加法,减法即会,掌握技巧轻松计算...
  7. 求杨辉三角的前n行数据_LeetCode算法第118题:杨辉三角
  8. 巧妙利用channel进行golang并发式爬虫
  9. 用python实现TCP协议传输功能(服务端代码)
  10. linux系统上传代码到gitlab服务器