- 浏览: 118400 次
- 性别:
- 来自: 宁波
文章分类
最新评论
spring Transaction Manager和hibernate session 吐血经验谈
文章分类:Java编程 关键字: spring transaction hibernate session记录我在使用spring,hibernate的时候遇到的session,和事务管理的问题.
spring用一个OpenSessionInView的filter来处理session was closed的问题.这个大家并不陌生.
我们项目当中的dao层有一个baseDao. 封装了一系列对持久化对象的操作方法.C,R,U,D 条件查询.分页查询.等等.而且baseDao当中的所有的find方法都是readOnly的,get和load直接调用的hibernateTemplate的get和load.当然service层当中的事务管理也是使用spring的那个事务模板.
以上配置都OK.
我遇到的问题有几个, 如下:
问题1,需要实现这样一个业务逻辑: 先把对象find出来.然后改变某个属性.然后在update. 在service当中就会写这样一个方法.changeOrder.在changeOrder当中先用dao的find.然后在用dao的update.理论上是可行的.因为service的事务都是被spring的事务模板托管.而且changeOrder得到的connection是可写的.(因为spring的事务模板根据对方法名的匹配来判断获得得connection类型).但是由于baseDao.当中的所有find方法都是 setReadyOnly(true). 这样.当在service执行任何find的时候.baseDao将强行把connection改为只读的.接下来在一个事务当中.任何update 和save动作都不能完成了.但是直接执行hibernateTemplate的get和load却不会出现这个问题.因为这个connection的属性是由spring的openSessionInView来处理的.在request一过来的时候spring会绑定一个session.到request.直至request结束.(在这段过程当中如果不认为改变connection的readOnly的属性.这个connection将会从请求一开始到结束都是可以写入的.)
解决的办法就是在自己的dao当中将find方法重载.将readOnly改为false.
问题2, 有两个方法.一个是get对象.一个是find对象.同样也是直接调用baseDao的get和find方法.
当我对一个对象进行编辑操作的时候发现service当中的update是有效的. 但是我find出来的对象.在利用service当中的update来更新却发现没有任何异常.但是就是更新不了对象.
后来才明白.get方法当中是没有对connection进行任何readOnly相关的操作.但是baseDao当中却设置了只读..这个时候又有一些疑问了. action并没有进行事务管理.当先调用service的find方法(也就是调用了baseDao中的find方法).这一个事务已经提交了.然后在继续调用service的update.为什么会更新不了对象?
原因就是在于OpenSessionInView.绑定的一个session对象在这一次的request当中.所以.从一次request.开始到结束.这个request仅仅会操作当前的一个session对象. 尽管在action当中连续调用的两次service方法都有两个不同的事务范围.在一整个请求当中还是只存在一个session对象.
所以第一个service的find方法执行完毕之后已经将当前request范围内的session改成了readOnly.以后的所有的service操作都是只读的.后面的service一些save或者update方法都会失效.....这就是OpenSessionInView和事务之间的微妙关系.
问题3,在ajax异步调用当中.经常也会出现这一系列的问题.其实原理大都是一样.因为ajax后来也是一个以.dwr结尾的请求.在OpenSessionInView当中加入一个filtermapping 为 .dwr 这样它会拦截所有的.dwr请求.在所有的ajax操作当中会绑定一个session对象.
总结一下: OpenSessionInView是一个filter.它会为每一个request绑定一个session.任何接下来在这一次请求当中所有的hibernate操作.都是基于当前请求的这个session的.任何service或者dao把当前的session对象改为了readOnly后.接下来所有save or update操作将进行不了.尽管他们不是在一个service方法(不是在同一个事务当中进行).
BTW.service在很大程度上是可以和dao层混合到一起.这样可以节约很多代码.但是.也会带来维护的时候非常的负责.并且麻烦.特别是readOnly 和session was closed问题.会另你非常的沮丧.
dao实际上是不需要用transaction来管理的.真正需要事务的是项目当中的service层.理解才是最重要的.用好OpenSessionInView会给项目带来极大的方便.
spring用一个OpenSessionInView的filter来处理session was closed的问题.这个大家并不陌生.
我们项目当中的dao层有一个baseDao. 封装了一系列对持久化对象的操作方法.C,R,U,D 条件查询.分页查询.等等.而且baseDao当中的所有的find方法都是readOnly的,get和load直接调用的hibernateTemplate的get和load.当然service层当中的事务管理也是使用spring的那个事务模板.
Java代码
- <bean id="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory">
- <ref local="sessionFactory" />
- </property>
- </bean>
- <bean id="txProxyTemplate" lazy-init="true" abstract="true"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager">
- <ref bean="transactionManager" />
- </property>
- <property name="transactionAttributes">
- <props>
- <prop key="save*">PROPAGATION_REQUIRED</prop>
- <prop key="del*">PROPAGATION_REQUIRED</prop>
- <prop key="update*">PROPAGATION_REQUIRED</prop>
- <prop key="create*">PROPAGATION_REQUIRED</prop>
- <prop key="add*">PROPAGATION_REQUIRED</prop>
- <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
- <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
- <prop key="*">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- </bean>
以上配置都OK.
我遇到的问题有几个, 如下:
问题1,需要实现这样一个业务逻辑: 先把对象find出来.然后改变某个属性.然后在update. 在service当中就会写这样一个方法.changeOrder.在changeOrder当中先用dao的find.然后在用dao的update.理论上是可行的.因为service的事务都是被spring的事务模板托管.而且changeOrder得到的connection是可写的.(因为spring的事务模板根据对方法名的匹配来判断获得得connection类型).但是由于baseDao.当中的所有find方法都是 setReadyOnly(true). 这样.当在service执行任何find的时候.baseDao将强行把connection改为只读的.接下来在一个事务当中.任何update 和save动作都不能完成了.但是直接执行hibernateTemplate的get和load却不会出现这个问题.因为这个connection的属性是由spring的openSessionInView来处理的.在request一过来的时候spring会绑定一个session.到request.直至request结束.(在这段过程当中如果不认为改变connection的readOnly的属性.这个connection将会从请求一开始到结束都是可以写入的.)
解决的办法就是在自己的dao当中将find方法重载.将readOnly改为false.
问题2, 有两个方法.一个是get对象.一个是find对象.同样也是直接调用baseDao的get和find方法.
当我对一个对象进行编辑操作的时候发现service当中的update是有效的. 但是我find出来的对象.在利用service当中的update来更新却发现没有任何异常.但是就是更新不了对象.
后来才明白.get方法当中是没有对connection进行任何readOnly相关的操作.但是baseDao当中却设置了只读..这个时候又有一些疑问了. action并没有进行事务管理.当先调用service的find方法(也就是调用了baseDao中的find方法).这一个事务已经提交了.然后在继续调用service的update.为什么会更新不了对象?
原因就是在于OpenSessionInView.绑定的一个session对象在这一次的request当中.所以.从一次request.开始到结束.这个request仅仅会操作当前的一个session对象. 尽管在action当中连续调用的两次service方法都有两个不同的事务范围.在一整个请求当中还是只存在一个session对象.
所以第一个service的find方法执行完毕之后已经将当前request范围内的session改成了readOnly.以后的所有的service操作都是只读的.后面的service一些save或者update方法都会失效.....这就是OpenSessionInView和事务之间的微妙关系.
问题3,在ajax异步调用当中.经常也会出现这一系列的问题.其实原理大都是一样.因为ajax后来也是一个以.dwr结尾的请求.在OpenSessionInView当中加入一个filtermapping 为 .dwr 这样它会拦截所有的.dwr请求.在所有的ajax操作当中会绑定一个session对象.
总结一下: OpenSessionInView是一个filter.它会为每一个request绑定一个session.任何接下来在这一次请求当中所有的hibernate操作.都是基于当前请求的这个session的.任何service或者dao把当前的session对象改为了readOnly后.接下来所有save or update操作将进行不了.尽管他们不是在一个service方法(不是在同一个事务当中进行).
BTW.service在很大程度上是可以和dao层混合到一起.这样可以节约很多代码.但是.也会带来维护的时候非常的负责.并且麻烦.特别是readOnly 和session was closed问题.会另你非常的沮丧.
dao实际上是不需要用transaction来管理的.真正需要事务的是项目当中的service层.理解才是最重要的.用好OpenSessionInView会给项目带来极大的方便.
发表评论
-
Open Session In View(转)
2010-12-04 21:58 1108英文原文:http://community.jboss.org ... -
open session in view 研究
2010-12-04 21:54 775在没有使用Spring提供的Open Session In V ... -
Hibernate并发控制
2010-12-04 19:46 10413. 多个事务并发引起的问题:3.1. 第 ... -
servlet和filter的异同
2010-12-04 19:28 990以前总以为filter就是一种特殊servlet,所以他们 ... -
JavaScript,调用函数的5种方法
2010-11-28 16:16 917JavaScript,调用函数的5种方法 一次又一次的,我发现 ... -
IOC原理
2010-11-28 09:18 850IOC(inview of control)控制反转 ... -
Hibernate级联操作Cascade学之---delete
2010-11-27 10:06 1024所在cascade,就是说我在更新一方的时候,可以根据这一 ... -
HTTP POST GET 本质区别详解
2010-11-27 09:47 859HTTP POST GET 本质区别详解 收藏 ... -
Hibernate二级缓存(转)
2010-11-27 09:38 803Hibernate二级缓存(转 ... -
加速你的Hibernate引擎(下)
2010-11-27 09:37 801加速你的Hibernate引擎(下) 文章分类:Ja ... -
加速你的Hibernate引擎(上)
2010-11-27 09:36 875加速你的Hibernate引擎(上) 文章分类:Ja ... -
浅析Spring提供的事务管理方法
2010-11-27 09:32 811浅析Spring提供的事务管理方法 2006-0 ... -
hibernate性能优化
2010-11-27 09:24 662转 hibernate性能优化 ... -
Hibernate 性能优化技巧
2010-11-27 09:23 765转 Hibernate 性能优化 ... -
Hibernate乐观锁实现之Timestamp
2010-11-27 09:21 882转 Hibernate乐观锁实现之Timestamp ... -
Hibernate乐观锁实现之Version
2010-11-27 09:21 839转 Hibernate乐观锁实现之Version ... -
Hibernate悲观锁定与乐观锁定区别
2010-11-27 09:20 702转 Hibernate悲观锁定 ... -
Hibernate二级缓存 ---- 最佳实践
2010-11-27 09:19 907转 Hibernate二级缓存 ---- 最佳实践 ... -
Spring如何与struts2结合
2010-11-22 12:34 9644.Spring如何与struts2结合 关键字: ... -
struts2 iterator
2010-11-21 21:12 928struts2的s:iterator 可以遍历 数据栈里面 ...
相关推荐
2. **配置Transaction Manager**:Spring提供PlatformTransactionManager接口来管理事务。在与Hibernate整合时,我们通常会使用HibernateTransactionManager,它基于Hibernate的Session管理事务。 3. **实体类和...
通过这种方式整合Spring和Hibernate,我们可以避免直接在代码中创建SessionFactory和Session,从而减少资源泄漏的风险,同时借助Spring的事务管理能力,简化事务处理。这种整合方式使得系统更加模块化,更易于维护和...
接下来,我们需要实现上述定义的泛型接口,并结合Spring框架来管理Hibernate的Session生命周期和事务处理。具体实现如下: ```java public class HibernateDaoImpl, PK extends Serializable> implements ...
在Java开发领域,Spring框架和Hibernate是两个非常重要的开源库,它们分别负责应用程序的依赖管理和对象关系映射(ORM)。Spring作为一个全面的轻量级框架,提供了强大的依赖注入、AOP(面向切面编程)以及各种企业...
在Hibernate中,你可以使用`Session`对象的`beginTransaction()`、`commit()`和`rollback()`方法来手动管理事务。例如,在一个业务服务方法中,你会先调用`beginTransaction()`,然后执行数据库操作,最后根据操作...
整合Spring和Hibernate的主要目的是利用Spring的管理能力来控制Hibernate的SessionFactory和Session,以及事务管理。下面我们将详细探讨整合的步骤和方法。 1. **配置环境**: - 首先,确保你的项目中包含了Spring...
`HibernateTransactionManager`是Spring提供的专门用于管理Hibernate事务的类,它会自动处理Hibernate Session和JDBC Connection的开启、提交、回滚。 三、配置Spring事务管理 在Spring的配置文件中,我们需要添加...
<tx:annotation-driven transaction-manager="transactionManager"/> ``` **2. dispatcher-servlet.xml**: - 配置Spring MVC的相关组件。 - 示例配置: ```xml <beans xmlns="http://www.springframework...
在IT行业中,Spring和Hibernate是两个非常重要的框架,它们分别在应用上下文管理和持久化层提供了强大的支持。本文将深入探讨如何将Spring与Hibernate整合,以便在SQL Server数据库上执行SQL操作。 首先,Spring...
- 最佳实践中,推荐使用HibernateTemplate或者HibernateDaoSupport,它们是Spring提供的对Hibernate的简单包装,可以避免手动管理Session和事务。 7. **测试与优化** - 使用JUnit进行单元测试,验证整合是否成功...
2. 配置Hibernate Transaction Manager:接着,配置HibernatePlatformTransactionManager,它实现了Spring的PlatformTransactionManager接口,使得Spring可以控制Hibernate的事务。 3. 配置事务传播行为:通过@...
2. **配置Hibernate SessionFactory**:在Spring的XML配置文件(如`applicationContext.xml`)中,你需要定义一个`SessionFactory` bean,它将负责创建和管理Hibernate的Session对象。这通常包括数据库连接参数、...
下面我们将详细介绍如何进行hibernate和Spring MVC的配置整合。 ### 1. 引入依赖 首先,你需要在项目中添加Spring MVC和Hibernate的相关依赖。通常在Maven或Gradle的pom.xml或build.gradle文件中,你需要引入以下...
2. **使用 HibernateTemplate**: Spring 为 Hibernate 提供了一个抽象层,即 HibernateTemplate 类,它封装了 Session 的常用操作,如保存、更新、删除和查询等,同时处理了事务管理和异常转换。在 Spring 容器中...
### Struts1.x、Spring2.x、Hibernate3.x 和 DWR2.x 整合知识点解析 #### 一、Struts1.x与Spring2.x的整合 **1.1 在web.xml中进行Struts和Spring的配置** 为了实现Struts1.x与Spring2.x的无缝集成,首先需要在...
整合 Spring 和 Hibernate 的目标是让 Spring 管理 Hibernate 的 Session,包括生命周期管理和事务处理。这通常涉及 Spring 的事务代理和 AOP(面向切面编程)。 **步骤1:配置 SessionFactory** 在 `...
【Xfire Spring Hibernate 发布WebService】是将Xfire、Spring和Hibernate这三种技术结合,用于在MyEclipse环境中创建和发布Web服务。Xfire是一个基于Java的SOAP和REST Web服务框架,Spring则提供了依赖注入和AOP...
通过上述步骤,我们完成了Spring、Hibernate和Struts1的整合,实现了数据访问、事务管理和业务逻辑的分离,提高了代码的可维护性和可扩展性。对于Struts2,其核心组件Action、Interceptor等与Spring的集成方式类似,...
在Java开发领域,Spring框架和Hibernate是两个非常重要的组件,它们分别在应用的事务管理和对象关系映射(ORM)方面发挥着关键作用。本教程将深入探讨如何结合这两个强大的工具来构建事务持久层,实现高效、灵活的...
- **统一事务管理**: Spring的事务管理可以统一管理Hibernate的Session,从而简化事务控制逻辑。 - **更好的测试支持**: Spring提供了方便的测试框架,可以很容易地模拟Hibernate环境进行单元测试。 **3.2 配置数据...