- 浏览: 115155 次
- 性别:
- 来自: 宁波
文章分类
最新评论
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 1075英文原文:http://community.jboss.org ... -
open session in view 研究
2010-12-04 21:54 754在没有使用Spring提供的Open Session In V ... -
Hibernate并发控制
2010-12-04 19:46 10153. 多个事务并发引起的问题:3.1. 第 ... -
servlet和filter的异同
2010-12-04 19:28 960以前总以为filter就是一种特殊servlet,所以他们 ... -
JavaScript,调用函数的5种方法
2010-11-28 16:16 884JavaScript,调用函数的5种方法 一次又一次的,我发现 ... -
IOC原理
2010-11-28 09:18 832IOC(inview of control)控制反转 ... -
Hibernate级联操作Cascade学之---delete
2010-11-27 10:06 950所在cascade,就是说我在更新一方的时候,可以根据这一 ... -
HTTP POST GET 本质区别详解
2010-11-27 09:47 832HTTP POST GET 本质区别详解 收藏 ... -
Hibernate二级缓存(转)
2010-11-27 09:38 773Hibernate二级缓存(转 ... -
加速你的Hibernate引擎(下)
2010-11-27 09:37 777加速你的Hibernate引擎(下) 文章分类:Ja ... -
加速你的Hibernate引擎(上)
2010-11-27 09:36 857加速你的Hibernate引擎(上) 文章分类:Ja ... -
浅析Spring提供的事务管理方法
2010-11-27 09:32 786浅析Spring提供的事务管理方法 2006-0 ... -
hibernate性能优化
2010-11-27 09:24 639转 hibernate性能优化 ... -
Hibernate 性能优化技巧
2010-11-27 09:23 732转 Hibernate 性能优化 ... -
Hibernate乐观锁实现之Timestamp
2010-11-27 09:21 855转 Hibernate乐观锁实现之Timestamp ... -
Hibernate乐观锁实现之Version
2010-11-27 09:21 807转 Hibernate乐观锁实现之Version ... -
Hibernate悲观锁定与乐观锁定区别
2010-11-27 09:20 677转 Hibernate悲观锁定 ... -
Hibernate二级缓存 ---- 最佳实践
2010-11-27 09:19 883转 Hibernate二级缓存 ---- 最佳实践 ... -
Spring如何与struts2结合
2010-11-22 12:34 9364.Spring如何与struts2结合 关键字: ... -
struts2 iterator
2010-11-21 21:12 902struts2的s:iterator 可以遍历 数据栈里面 ...
相关推荐
可以对hibernate的 Session 和 Transaction 有更深入的认识 希望对一些概念比较模糊的人 有帮助
NULL 博文链接:https://stewchicken.iteye.com/blog/938875
spring-hibernate-maven-transaction整合
FactoryTalk Transaction Manager 用户手册,便于了解产品配置等
里面为一个演示spring事务传播机制的小demo。简单实现转账功能,通过添加注解调整传播级别,同时通过日志打印查看sql是否执行,在mysql中的数据是否发生了变化(操作提交还是回滚了)。
在使用maven开发web项目极大地方便了jar包的...oejpw.PlusConfiguration:No Transaction manager found - if your webapp requires one, please configure one. 而且启动过程会暂停十几秒,在反复调试代码时很浪费时间
在准备整合Spring之前,也在网上看了各种配置。但是楼主心里还是很纠结,...楼主还是一步一步的来吧,感觉Spring操作Hibernate还是离不开DataSource,SessionFactory,Transaction这几个要素。 详细说明看我的博客文章。
Transaction tx1 = session1.beginTransaction(); // 先加载一个持久化对象 Customer customer = (Customer)session.get(Customer.class, new Long(1)); session.delete(customer); // 计划执行一个delete语句
spring-transaction.jar.zip
Learn how to use the core Hibernate APIs and tools as part of the Spring Framework. This book illustrates how these two frameworks can be best utilized. Other persistence solutions available in Spring...
Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: JDBC rollback failed 这表明Hibernate事务回滚操作失败,导致事务不能正确回滚。 二、问题原因 该问题的...
spring 3.2.0+hibernate 4.1.6+struts2整合需要的jar包 的目录 antlr-2.7.7.jar aopalliance-1.0.jar asm-3.3.jar asm-commons-3.3.jar aspectjweaver-1.5.3.jar bonecp-0.7.1.RELEASE.jar cglib-2.1.3.jar ...
Spring提供了org.springframework.orm.hibernate3.HibernateTemplate类和org.springframework.orm.hibernate3.HibernateCallback接口来方便和Hibernate整合。 HibernateTemplate类封装了Hibernate的主要类,它提供了...
Spring在Transaction事务传播行为种类,希望对大家有所帮助
NULL 博文链接:https://wsjjasper.iteye.com/blog/1570448
org.springframework.transaction-3.2.2.RELEASE最新版本
一个简单的spring+hibernate+mysql 事务实例
该软件依赖包,为实例spring aop实现Hinernate事务操作软件包
hibernate概述,hibernate入门Demo,hibernate配置文件详解(全局配置,实体类映射配置),配置实体规则,核心API详解(Configuration,sessionFactory,session,Transaction),hibernate中的对象状态以及刷新能缓存机制 ...
org.springframework.transaction-3.1.1.RELEASE.jar org.springframework.web-3.1.1.RELEASE.jar org.springframework.web.portlet-3.1.1.RELEASE.jar org.springframework.web.servlet-3.1.1.RELEASE.jar org....