spring 控制hibernate的session何时关闭.
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何时关闭.相关推荐
- (继续搬)struts日期格式的转换以及hibernate中session的关闭在xml中的配置
1.struts日期格式的转换package cn.sxx.utils;import java.text.ParseException; import java.text.SimpleDateForm ...
- hibernate 管理 Session(单独使用session,非spring)
hibernate 管理 Session(单独使用session,非spring) Hibernate 自身提供了三种管理 Session 对象的方法 Session 对象的生命周期与本地线程绑定 S ...
- Spring boot 解决 hibernate no session异常
Spring boot 解决 hibernate no session异常 参考文章: (1)Spring boot 解决 hibernate no session异常 (2)https://www. ...
- 在将hibernate的session托管给spring过程中的问题
No CurrentSessionContext configured ------Hibernate 出现上面的错误提示:如果是只有hibernate的配置则: org.hibernate.Hibe ...
- 整合Struts2、Spring、Hibernate构建J2EE应用
[论文摘要] J2EE即是以Java 2平台为基础的体系结构,又是一组旨在简化企业解决方案的开发.部署.运行.维护等相关复杂问题的技术规范与指南.Struts2.Spring.Hibernate是当今 ...
- spring和hibernate的整合
阅读目录 一.概述 二.整合步骤 1.大致步骤 2.具体分析 一.概述 Spring整合Hibernate有什么好处? 1.由IOC容器来管理Hibernate的SessionFactory 2.让H ...
- ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存
ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate : Hibernate是一个持久层框架,经常访问物理数据库 ...
- Spring+SpringMVC+Hibernate整合操作数据库 概述
概述 Hibernate是一款优秀的ORM框架,能够连接并操作数据库,包括保存和修改数据.Spring MVC是Java的web框架,能够将Hibernate集成进去,完成数据的CRUD.Hibern ...
- .netcore 如何获取系统中所有session_集群化部署,Spring Security 要如何处理 session 共享?
前面和大家聊了 Spring Security 如何像 QQ 一样,自动踢掉已登录用户(Spring Boot + Vue 前后端分离项目,如何踢掉已登录用户?),但是前面我们是基于单体应用的,如果我 ...
最新文章
- [转]VS2010安装说明及所有安装出错的解决办法
- 3-1 Point类的构造函数_JAVA
- AAAI21最佳论文Informer:效果远超Transformer的长序列预测神器???
- Python基础——PyCharm版本——第三章、数据类型和变量(超详细)
- vue中的数据单向绑定,判断,循环,函数
- 魔方财务对接码支付插件
- python学习(6)--logging打印日志
- 光储充一体化充电站_忙时给车充电 闲时上网供电 多能电动车充电站在乐清投用...
- 力扣-61 旋转链表
- 20 个实例玩转 Java 8 Stream,写的太好了!
- java实现行政区域划分_java解析中国行政区域并在页面显示实现动态逐级筛选
- 从2D图像生成3D模型,基于Im2Avatar
- [2022-04-27] refresh PDB
- 如何在图片上添加边框和文字
- Scrapy 2.6 Requests and Responses 请求和响应使用指南
- 忘记mysql的root密码啷个办
- mac安装golang,编写第一个go程序
- 14宽的键槽深度多少_平键和键槽标准尺寸规格表.doc
- 问题-某个程序改了ICO图标后编译后还是显示老图标?
- 2019初创企业投融资服务平台都有哪些?
热门文章
- mybatis应用(二)注解的实现
- vim树形目录NERDTree
- 【Linux】一步一步学Linux——exec命令(208)
- 【Linux】一步一步学Linux——wc命令(52)
- 【Linux系统编程】进程间通信--共享内存
- 两个多精度十进制数加法程序设计_初中数学之有理数的加减,学会加法,减法即会,掌握技巧轻松计算...
- 求杨辉三角的前n行数据_LeetCode算法第118题:杨辉三角
- 巧妙利用channel进行golang并发式爬虫
- 用python实现TCP协议传输功能(服务端代码)
- linux系统上传代码到gitlab服务器