`
footman265
  • 浏览: 118400 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

spring Transaction Manager和hibernate session

    博客分类:
  • SSH
阅读更多

 

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的那个事务模板. 
Java代码 
  1. <bean id="transactionManager"  
  2.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  3.         <property name="sessionFactory">  
  4.             <ref local="sessionFactory" />  
  5.         </property>  
  6.     </bean>  
  7.       
  8.        
  9.     <bean id="txProxyTemplate" lazy-init="true" abstract="true"  
  10.         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
  11.         <property name="transactionManager">  
  12.             <ref bean="transactionManager" />  
  13.         </property>  
  14.         <property name="transactionAttributes">  
  15.             <props>  
  16.                 <prop key="save*">PROPAGATION_REQUIRED</prop>  
  17.                 <prop key="del*">PROPAGATION_REQUIRED</prop>  
  18.                 <prop key="update*">PROPAGATION_REQUIRED</prop>  
  19.                 <prop key="create*">PROPAGATION_REQUIRED</prop>  
  20.                 <prop key="add*">PROPAGATION_REQUIRED</prop>  
  21.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>  
  22.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>  
  23.                 <prop key="*">PROPAGATION_REQUIRED</prop>  
  24.             </props>  
  25.         </property>  
  26.     </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会给项目带来极大的方便. 

 

分享到:
评论

相关推荐

    spring+hibernate整合实现简单数据库添加记录

    2. **配置Transaction Manager**:Spring提供PlatformTransactionManager接口来管理事务。在与Hibernate整合时,我们通常会使用HibernateTransactionManager,它基于Hibernate的Session管理事务。 3. **实体类和...

    JavaEE spring和Hibernate整合(没有hibernate.cfg.xml)

    通过这种方式整合Spring和Hibernate,我们可以避免直接在代码中创建SessionFactory和Session,从而减少资源泄漏的风险,同时借助Spring的事务管理能力,简化事务处理。这种整合方式使得系统更加模块化,更易于维护和...

    Spring/泛型Hibernate的实现

    接下来,我们需要实现上述定义的泛型接口,并结合Spring框架来管理Hibernate的Session生命周期和事务处理。具体实现如下: ```java public class HibernateDaoImpl, PK extends Serializable&gt; implements ...

    spring集成hibernate所需jar包

    在Java开发领域,Spring框架和Hibernate是两个非常重要的开源库,它们分别负责应用程序的依赖管理和对象关系映射(ORM)。Spring作为一个全面的轻量级框架,提供了强大的依赖注入、AOP(面向切面编程)以及各种企业...

    Hibernate编程式事务与Spring Aop的声明式事务(spring与hibernate集成)

    在Hibernate中,你可以使用`Session`对象的`beginTransaction()`、`commit()`和`rollback()`方法来手动管理事务。例如,在一个业务服务方法中,你会先调用`beginTransaction()`,然后执行数据库操作,最后根据操作...

    Spring和Hibernate的整合操作示例

    整合Spring和Hibernate的主要目的是利用Spring的管理能力来控制Hibernate的SessionFactory和Session,以及事务管理。下面我们将详细探讨整合的步骤和方法。 1. **配置环境**: - 首先,确保你的项目中包含了Spring...

    spring3、 hibernate4 配置声明式事务管理(annotation方式)

    `HibernateTransactionManager`是Spring提供的专门用于管理Hibernate事务的类,它会自动处理Hibernate Session和JDBC Connection的开启、提交、回滚。 三、配置Spring事务管理 在Spring的配置文件中,我们需要添加...

    java8+tomcat8+struts2.5+spring4.3+hibernate5.2框架搭建详细过程

    &lt;tx:annotation-driven transaction-manager="transactionManager"/&gt; ``` **2. dispatcher-servlet.xml**: - 配置Spring MVC的相关组件。 - 示例配置: ```xml &lt;beans xmlns="http://www.springframework...

    Spring集成Hibernate写SQLServer

    在IT行业中,Spring和Hibernate是两个非常重要的框架,它们分别在应用上下文管理和持久化层提供了强大的支持。本文将深入探讨如何将Spring与Hibernate整合,以便在SQL Server数据库上执行SQL操作。 首先,Spring...

    hibernate3.5与spring2.5.5整合最佳实践

    - 最佳实践中,推荐使用HibernateTemplate或者HibernateDaoSupport,它们是Spring提供的对Hibernate的简单包装,可以避免手动管理Session和事务。 7. **测试与优化** - 使用JUnit进行单元测试,验证整合是否成功...

    Spring2.0+Hibernate3.1的事务管理

    2. 配置Hibernate Transaction Manager:接着,配置HibernatePlatformTransactionManager,它实现了Spring的PlatformTransactionManager接口,使得Spring可以控制Hibernate的事务。 3. 配置事务传播行为:通过@...

    spring3+hibernate4声明式事务配置(xml方式)

    2. **配置Hibernate SessionFactory**:在Spring的XML配置文件(如`applicationContext.xml`)中,你需要定义一个`SessionFactory` bean,它将负责创建和管理Hibernate的Session对象。这通常包括数据库连接参数、...

    hibernate和spring MVC配置整合

    下面我们将详细介绍如何进行hibernate和Spring MVC的配置整合。 ### 1. 引入依赖 首先,你需要在项目中添加Spring MVC和Hibernate的相关依赖。通常在Maven或Gradle的pom.xml或build.gradle文件中,你需要引入以下...

    spring整合Hibernate学习笔记.docx

    2. **使用 HibernateTemplate**: Spring 为 Hibernate 提供了一个抽象层,即 HibernateTemplate 类,它封装了 Session 的常用操作,如保存、更新、删除和查询等,同时处理了事务管理和异常转换。在 Spring 容器中...

    Struts1.x Spring2.x Hibernate3.x DWR2.x整合工具文档v1.00

    ### Struts1.x、Spring2.x、Hibernate3.x 和 DWR2.x 整合知识点解析 #### 一、Struts1.x与Spring2.x的整合 **1.1 在web.xml中进行Struts和Spring的配置** 为了实现Struts1.x与Spring2.x的无缝集成,首先需要在...

    图解SSH(struts2,spring,hibernate)框架配置步骤

    整合 Spring 和 Hibernate 的目标是让 Spring 管理 Hibernate 的 Session,包括生命周期管理和事务处理。这通常涉及 Spring 的事务代理和 AOP(面向切面编程)。 **步骤1:配置 SessionFactory** 在 `...

    Xfire Spring Hibernate 发布WebService

    【Xfire Spring Hibernate 发布WebService】是将Xfire、Spring和Hibernate这三种技术结合,用于在MyEclipse环境中创建和发布Web服务。Xfire是一个基于Java的SOAP和REST Web服务框架,Spring则提供了依赖注入和AOP...

    三大框架整合(Spring+Hibernate+Struts1/Struts2)

    通过上述步骤,我们完成了Spring、Hibernate和Struts1的整合,实现了数据访问、事务管理和业务逻辑的分离,提高了代码的可维护性和可扩展性。对于Struts2,其核心组件Action、Interceptor等与Spring的集成方式类似,...

    用Hibernate和Spring开发事务持久层.rar_spring

    在Java开发领域,Spring框架和Hibernate是两个非常重要的组件,它们分别在应用的事务管理和对象关系映射(ORM)方面发挥着关键作用。本教程将深入探讨如何结合这两个强大的工具来构建事务持久层,实现高效、灵活的...

    Struts+Spring+Hibernate整合教程

    - **统一事务管理**: Spring的事务管理可以统一管理Hibernate的Session,从而简化事务控制逻辑。 - **更好的测试支持**: Spring提供了方便的测试框架,可以很容易地模拟Hibernate环境进行单元测试。 **3.2 配置数据...

Global site tag (gtag.js) - Google Analytics