- 浏览: 58365 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
9976:
讲得很清晰详细,基本理解了~
JMS入门 -
robin35java:
这篇文章好,对于信号量进行了解释,并且扩展了线程的实现思考方式 ...
JAVA线程间通信问题 -
ds3783:
其实上述的问题总归起来还是架构设计不明确,Service层是否 ...
spring Transaction Manager和hibernate session 吐血经验谈 -
ivyloo:
好东西呀!谢谢了
JAVA基础
spring Transaction Manager和hibernate session 吐血经验谈
关键字: 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的那个事务模板.
- <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>
<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会给项目带来极大的方便.
评论
1 楼
ds3783
2009-08-24
其实上述的问题总归起来还是架构设计不明确,Service层是否可以访问Session?
界面层是否能够访问Session?
如果前两个问题是Y的话,那么DAO层起什么作用,DAO层与Service层以及web层如何做到职责分离?
最后PO为什么要绑session(在PO中没有大字段的情况下)?
我们是不是要回到CMP的时代?
界面层是否能够访问Session?
如果前两个问题是Y的话,那么DAO层起什么作用,DAO层与Service层以及web层如何做到职责分离?
最后PO为什么要绑session(在PO中没有大字段的情况下)?
我们是不是要回到CMP的时代?
发表评论
-
POI操作EXCEL
2009-07-20 16:58 3178public class SummaryHSSF { ... -
JAVA线程间通信问题
2009-04-23 17:51 8351问题 在前一小节,介绍了在多线程编程中使用同步机制的重要性, ... -
JMS
2009-04-23 10:41 1732JMS编程知识 关键字: jms ... -
Spring AOP 2
2009-04-11 14:18 915Spring AOP高级篇(自动 ... -
Spring AOP
2009-04-11 14:17 1011Spring AOP(2008-12-19 20:23:5 ... -
apache+tomcat配置
2009-04-10 17:48 2397apache+tomcat配置[转] 2007-10-27 ... -
apache+tomcat集群配置
2009-04-10 17:06 6929APACHE 2.2.8+TOMCAT6.0.14配置负载均衡 ... -
JMS 消息头
2009-04-09 23:28 2633深入掌握JMS(六):消息头 2009年03月31日 星期二 ... -
JMS topic
2009-04-09 23:26 3944深入掌握J ... -
深入掌握JMS(四):实战Queue
2009-04-09 23:24 2042Queue实现的是点到点模型,在下面的例子中,启动2个消费者共 ... -
深入掌握JMS(三):MessageListener
2009-04-09 23:22 55792009年03月31日 星期二 09:41 ... -
JMS例子
2009-04-09 23:19 3809深入掌握JMS(二):一个JMS例子 2009年03月31日 ... -
JMS入门
2009-04-09 23:17 21141. JMS基本概念 JMS( ... -
rmi 入门
2009-04-09 23:09 1183转]RMI实例入门(2009-02-26 ... -
java 23种模式代码
2009-04-09 02:07 148723种设计模式的代码版(Java) Posted on ... -
JAVA基础
2009-04-08 01:22 13701 【JAVA】JAVA相关基础知识 ... -
抽象工厂模式代码
2009-03-27 01:12 4150爪哇语言抽象工厂创立性模式介绍 工厂模 ... -
spring 事务传播机制
2009-03-26 19:29 1346Spring事务传播机制 PROPAG ... -
Spring声明式事务管理源码解读之事务提交
2009-03-26 19:27 1404/** *作者:张荣华(ahuaxuan) *2007-0 ...
相关推荐
在Java的持久化框架Hibernate中,`Session`和`Transaction`是两个至关重要的概念,它们在数据管理和事务处理中起到核心作用。这篇文章将深入解析这两个概念及其相关知识点。 `Session`是Hibernate提供的一种与...
本文将深入探讨Hibernate Session的几种释放模式,以及它们在实际开发中的应用和优缺点。 1. **Transaction边界Session(Transaction Bound Session)** 这是最常见的Session管理方式,通常与Spring的@...
本文将深入研究Hibernate中的`Session`和`Transaction`,这两个概念是理解Hibernate工作原理的关键。 首先,让我们了解`Session`。在Hibernate中,`Session`充当了应用程序与数据库之间的桥梁,它是持久化操作的...
在Spring和Hibernate的整合中,Spring可以作为Hibernate的容器,管理SessionFactory和Transaction,这样我们就能够在Spring的管理下进行数据库操作。通过@PersistenceContext注解,Spring可以注入EntityManager,@...
Spring、SpringMVC和Hibernate是Java开发中常用的三大框架,它们共同构成了SSH(Spring, SpringMVC, Hibernate)架构,广泛应用于企业级Web应用的开发。这个压缩包文件的标题和描述表明,它包含了使用Spring 3.0、...
Spring 和 Hibernate 的整合是企业级 Java 应用开发中的常见实践,它将 Spring 框架的控制反转(IoC)和面向切面编程(AOP)优势与 Hibernate 的持久化能力相结合,提供了更高效、灵活的数据库操作。下面我们将深入...
【Spring与Hibernate、Maven和Transaction的整合】 在现代Java Web开发中,Spring框架、Hibernate持久化工具和Maven构建工具是不可或缺的部分。Spring提供了强大的依赖注入和面向切面编程能力,Hibernate则简化了...
【hibernate与Session详解】 Hibernate 是一个强大的Java对象关系映射(ORM)框架,它为开发者提供了在Java应用程序中操作数据库...学习并熟练掌握Hibernate和Session,对于提升Java开发的效率和质量有着重要的作用。
在实际应用中,通常推荐使用Transaction模板或者Spring的HibernateTemplate或JpaTemplate,它们可以帮助你更好地管理Session和事务。例如,Spring的`@Transactional`注解可以自动管理事务的生命周期,使得代码更加...
- **Session和Transaction管理**:Hibernate提供Session接口处理数据库会话,同时支持JTA和JTASessionContext,便于事务管理。 - **HQL和QBC**:Hibernate Query Language (HQL) 是面向对象的查询语言,类似SQL。...
在Java Web开发领域,Spring、Struts和Hibernate是三个非常重要的框架,它们分别负责不同的职责。Spring是一个全面的后端框架,提供了依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)等核心特性;Struts是...
本文将详细探讨Spring与Hibernate的集成,特别是如何在集成环境中使用和管理`Session`。 首先,Spring作为一个轻量级的框架,提供了强大的依赖注入(DI)和面向切面编程(AOP)功能,它可以帮助我们解耦应用程序...
本篇将详细介绍如何使用Maven来构建一个结合Spring3 MVC和Hibernate的Web应用。 **一、Maven基础** 1. Maven仓库:Maven通过中央仓库下载项目所需的依赖,包括JAR包、源码、文档等。 2. `pom.xml`:项目对象模型...
2. **配置Transaction Manager**:Spring提供PlatformTransactionManager接口来管理事务。在与Hibernate整合时,我们通常会使用HibernateTransactionManager,它基于Hibernate的Session管理事务。 3. **实体类和...
Spring可以帮助管理Hibernate的SessionFactory和Transaction,提供声明式事务管理,以及通过AOP(面向切面编程)实现更灵活的持久化处理。 描述中的"ssh整合"指的是Struts、Spring和Hibernate的集成,这是一种常见...
综上所述,理解和熟练掌握Hibernate中的Session管理对于开发高效、健壮的Java应用程序至关重要。正确地使用Session,结合事务控制、查询语言和缓存策略,可以显著提升数据库操作的效率和应用的整体性能。
本资源提供的"软件依赖包(Spring AOP+Hibernate Transaction)"正是这样一种集合,它包含了Spring AOP和Hibernate Transaction管理的jar文件,使得开发者能够便捷地在Java应用中实现面向切面的编程(AOP)以及事务...
通过这种方式整合Spring和Hibernate,我们可以避免直接在代码中创建SessionFactory和Session,从而减少资源泄漏的风险,同时借助Spring的事务管理能力,简化事务处理。这种整合方式使得系统更加模块化,更易于维护和...
2. **配置文件**:编写`applicationContext.xml`(Spring配置)和`hibernate.cfg.xml`(Hibernate配置),定义bean、数据源、session工厂等,并配置数据库连接参数。 3. **实体类和映射文件**:创建Java实体类来...
Spring通过其DataSource和Transaction Manager组件来管理数据库连接和事务,同时通过HibernateTemplate或SessionFactoryBean来与Hibernate进行交互,这样既保留了Spring的灵活性,又利用了Hibernate的强大持久化能力...