`
qqjavagood
  • 浏览: 98552 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

Spring的事务,经典配(载)

    博客分类:
  • java
阅读更多
    spring的事务
今天对 spring 的 aop 事务有了一个新的认识,所以赶紧把今天的学习记下来,希望在今后的学习中能够起到一些作用,也能对今天的认识做一次总结。


1.spring 分享

先看一段代码:
   
connection conn = conn.getconnection();    conn.setautocommit(false);    ……..    ……...    conn.rollback();    conn.commit();


    数据库的事务是针对 connection 的。

     接着再看一段代码:( spring 中事务的一段学习代码,这段代码是把 spring 和 hibernate 结合在一起的,增加了理解上的难度,因为我的出发点一开始不要 hibernate ,就光用 jdbc 来进行数据库事务,但是没有其他好的代码,就这样吧)

  
 public long addlineitem(long orderid, lineitem lineitem){       log("orderlistdaohibernate.addlineitem : start...");       orderlist orderlist = (orderlist) gethibernatetemplate().load(orderlist.class, orderid);       lineitem.setorderlist(orderlist);       gethibernatetemplate().saveorupdate(lineitem);       gethibernatetemplate().saveorupdate(orderlist);       log("orderlistdaohibernate.addlineitem : ending...");       return lineitem.getid();    }

    在这个代码的配置文件中,把 addlineitem 做为一个切入点,进行事务,也就是说,在 addlineitem 的外面,再包上一层事务的外壳。

     但是这个时候,问题出来了,事务是针对 connection 的,而上面的两个连续的 hibernatetemplate 执行的  saveorupdate 中的 connection 必须是一致才能用事务, spring 怎么做到这一点的呢?(这个问题也就是在找  spring 的事务例子前,我想的 spring 中用 jdbc 来进行事务,怎么样让 connection 保持一致呢?但是没有 jdbc  的例子,只有整合 hibernate 或者 ibatis 的例子,但是,我想,原理是一样的吧。)



    解决问题的思路: hibernatetemplate 中的 connection 必定一致。那么就从 hibernatetemplate 入手。

     看 spring 的源代码,既然是 hibernate ,那么,就没有 connection 给你看,只有 session ,由  session 来管理 connection ,那么用事务来控制的话,这个 session 必定在所有该事务中是一致的。于是在  hibernatetemplate 中找到:


protected session getsession() {       if (isalwaysusenewsession()) {return sessionfactoryutils.getnewsession(getsessionfactory(), getentityinterceptor());       }       else if (!isallowcreate()) {return sessionfactoryutils.getsession(getsessionfactory(), false);       }       else {return sessionfactoryutils.getsession(                  getsessionfactory(), getentityinterceptor(), getjdbcexceptiontranslator());       }    }



看来在 sessionfactoryutils 里面,接着在 sessionfactoryutils.getsession 中找:



这个方法太长了,太复杂了,从简,发现了非常关键的一点:



sessionholder sessionholder = (sessionholder) transactionsynchronizationmanager.getresource(sessionfactory);




假如 sessionholder 不等于空,说明,在事务中有这样一个还没有 commit 的 session ,那么就返回这个 session ,假如等于空,新建一个 session ,并且在事务里加入这个 session 。这段代码的意思大概是这样,太繁杂了,只能猜,也肯定是如此。



再看 gethibernatetemplate() 方法来自继承 hibernatedaosupport ,看了电子书《 spring- reference 》的第九章“ dao 支持”, dao 的支持类可以有好多,如: jdbcdaosupport ,  hibernatedaosupport , jdodaosupport 等等。



既然前面一开始就是从  jdbc 的 spring 事务控制引起的,那么看到了同样的 hibernatedaosupport---jdbcdaosupport ,那么  jdbcdaosupport 也应该有 getjdbctemplate() 这个方法,并且返回 jdbctemplate 这个类。



果然如此。



于是剖析 jdbctemplate 是不是和 hibernatetemplate 一样。果然一样。



注意到:

connection con = datasourceutils.getconnection(getdatasource());




connection 是从 datasourceutils.getconnection() 来的,继续跟踪 datasourceutils.getconnection() 。



找到:

connectionholder conholder = (connectionholder) transactionsynchronizationmanager.getresource(datasource);




和 hibernate 中的一模一样,因为没有了 session 的封装,条理在 jdbc 中更加清晰了。



至此, spring 的事务控制 已经全部搞定。

2.spring 事务管理的配置

看了上面同事学习 spring 的笔记后自己也觉得有新的理解,从什么地方说起呢?就从 spring 的事务配置说起吧。那么我们看看 contextconfig.xml 吧。

<bean id="sessionfactory" class="org.springframework.orm.hibernate.localsessionfactorybean">       <property name="datasource">           <ref bean="datasource" />       </property>       <property name="mappingresources">           <list>              <value>mf/org/user/user.hbm.xml</value>           </list>       </property></bean><bean id="transactionmanager" class="org.springframework.orm.hibernate.hibernatetransactionmanager">       <property name="sessionfactory">           <ref local="sessionfactory" />       </property>    </bean><bean id="txproxytemplate" abstract="true" class="org.springframework.transaction.interceptor.transactionproxyfactorybean">       <property name="transactionmanager">           <ref bean="transactionmanager" />       </property>       <property name="transactionattributes">           <props><prop key="save*">propagation_required,-exception</prop><prop key="remove*">propagation_required,-exception </prop><prop key="update*">propagation_required,-exception </prop><prop key="incress*">propagation_required,-exception </prop><prop key="*">propagation_required,readonly</prop>           </props>       </property>    </bean><bean id="usermanager" parent="txproxytemplate">       <property name="target" ref="usermanagertarget" /></bean><bean id="usermanagertarget"class=" mf.org.hb.user.service.impl.usermanagerimpl">       <property name="userdao" ref="userdao" /></bean><bean id="userdao" class="mf.org.hb.user.dao.hibernate.userdaohibernate">       <property name="sessionfactory" ref="sessionfactory" /></bean>

    以上就是一个完整的 spring 配置,是不是很熟悉呢,这里是用的 appfuse 的框架,呵呵。有那么点味道吧。

    首先我们看看

<bean id="transactionmanager" class="org.springframework.orm.hibernate.hibernatetransactionmanager">       <property name="sessionfactory">           <ref local="sessionfactory" />       </property></bean>

    这一个 bean 让 spring 为我们注入了什么呢?事务,对!我们把 hibernate 的事务注入到了 spring 的 ioc 容器之中了。然后我们再看看:

  
 <bean id="txproxytemplate" abstract="true" class="org.springframework.transaction.interceptor.transactionproxyfactorybean">       <property name="transactionmanager">           <ref bean="transactionmanager" />       </property>       <property name="transactionattributes">           <props><prop key="save*">propagation_required,-exception</prop><prop key="remove*">propagation_required,-exception </prop><prop key="update*">propagation_required,-exception </prop><prop key="incress*">propagation_required,-exception </prop><prop key="*">propagation_required,readonly</prop>           </props>       </property></bean>

    这个 bean 又是让 spring 为我们注入了了什么呢?事务代理,对了!我们把事务的代理交给一个 txproxytemplate 的去做了,这样的好处我待会再说,现在我们看看下面的一些配置信息。

<prop key="save*">propagation_required,-exception</prop><prop key="remove*">propagation_required,-exception </prop><prop key="update*">propagation_required,-exception </prop><prop key="incress*">propagation_required,-exception </prop><prop key="*">propagation_required,readonly</prop>

这里就是事务处理时如果遇到异常信息,或者其他的原因时我们要求 spring 把当前的事务回滚了,这样才能不至于在数据库中产生垃圾啊。我们规定所有的  save,remove,update,incress 这样的方法开头的在出现一些问题后把事务给回滚了,看看我们写的:  propagation_required,-exception 。

有人就会说 propagation_required 就可以回滚事务啊,为什么加上 ,-exception 呢?其实我以前也时这样想的,但这是不完全正确的,当然我们在处理一个事务时只要有一个  propagation_required 就可以了,但是当我们的业务逻辑中要求我们在一个事务代理中开启两个事务,这两个事务表面上没有联系,但是实际中又有很多联系的,比如我们上传附件和提交文档,这样两个操作我们可以分开,因为他们不是往一个表里插入数据,我们又不希望这两个操作写在一个  service 里,这样我们要是有一个业务只要上传附件呢?那样我们是不是又要再写一个方法啊!所以在开启两个事务时如果有一个抛出异常了,我们就要把上一个提交的事务回滚了,这样做我们就要用的 -exception 了,这样就完全满足我们的要求了,我也试过如果我写的是  propagation_required,-sqlexception 时,这样我们只会在出现 sqlexception 时事务回顾,出现其他的异常事务就不回滚了,好在 spring 可以让我们写如异常的基类就可以做到捕获任何异常,这样我们就写 -exception 好了。特殊情况在特殊处理吧。通用情况下我们还是这样的。

我们再看看:

<bean id="usermanager" parent="txproxytemplate">       <property name="target" ref="usermanagertarget" /></bean><bean id="usermanagertarget"class="mf.org.hb.user.service.impl.usermanagerimpl">       <property name="userdao" ref="userdao" /></bean><bean id="userdao" class="mf.org.hb.user.dao.hibernate.userdaohibernate">       <property name="sessionfactory" ref="sessionfactory" /></bean>    当然我们也可以写成:<bean id="usermanager" parent="txproxytemplate">       <property name="target">           <bean class="mf.org.hb.user.service.impl.usermanagerimpl">              <property name="userdao">                  <ref bean="userdao"/>              </property>           </bean>       </property></bean><bean id="userdao" class="mf.org.hb.user.dao.hibernate.userdaohibernate">       <property name="sessionfactory" ref="sessionfactory" /></bean>



这下我们解除以前的疑惑, parent="txproxytemplate" 知道我们为什么在上面先写了 txproxytemplate 的  bean 了吧,这样我们就没有必要再写一编了。是不是很方便? spring 的这些技巧还不只这些呢。这样我们就可以轻松利用以上这三个注入的类去做我们的逻辑了。

spring 就是要我们注入实现类,然后使用接口操作,这样耦合性就不是那么强了,这也体现了 spring 的工厂模式。而 aop 的 manager 又象我们熟知的代理模式吧 !

3.注意要点

在写配置的时候注意各个 manager 和 dao 之间的关系,以及 <ref= ”” > 之间的关系,清晰里面的关系才能更好的配置
原文:http://dev.firnow.com/course/3_program/java/javajs/200853/112246.html 
0
8
分享到:
评论

相关推荐

    Spring事务管理Demo

    Spring事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何实现事务的管理。 首先,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 ...

    spring事务与数据库操作

    ### Spring事务与数据库操作 #### 一、Spring的声明式事务管理 在现代软件开发中,事务处理是非常关键的一部分,特别是在涉及多个数据操作时。Spring框架提供了强大的事务管理能力,可以方便地集成到应用程序中。...

    Spring事务流程图

    Spring事务管理是Spring框架的核心特性之一,主要用于处理应用程序中的数据一致性问题。在Spring中,事务管理分为编程式和声明式两种方式。本篇文章将详细解释Spring事务管理的流程,以及如何通过时序图来理解这一...

    Spring事务原理、Spring事务配置的五种方式

    Spring事务原理和配置 Spring事务原理是指Spring框架中的一种机制,用于管理事务,并提供了多种配置方式。事务是指一系列的操作,作为一个整体执行,如果其中某个操作失败,整个事务将回滚。Spring事务原理围绕着两...

    Spring事务管理开发必备jar包

    本资源包提供了进行Spring事务管理开发所需的所有关键库,包括框架基础、核心组件、AOP(面向切面编程)支持、日志处理、编译工具以及与数据库交互的相关jar包。下面将对这些知识点进行详细解释: 1. **Spring框架*...

    spring事务案例分析.zip

    本主题将深入探讨“Spring事务案例分析.zip”中的关键知识点,包括Spring事务管理及其在实际项目中的应用。 首先,我们来了解什么是Spring事务管理。在分布式系统或数据库操作中,事务管理是确保数据一致性和完整性...

    spring 事务传播 demo

    在Spring框架中,事务管理是核心特性之一,它允许开发者以声明式或编程式的方式处理事务。本示例“spring 事务传播 demo”将聚焦于Spring的事务传播行为,这是在多个方法调用中控制事务边界的关键概念。下面我们将...

    Spring事务小demo

    这个名为"Spring事务小demo"的项目提供了一个实践示例,帮助开发者了解Spring事务处理的基本概念和用法。 首先,Spring事务管理是Spring框架的核心特性之一,它允许我们以声明式或编程式的方式管理事务。声明式事务...

    Spring 事务简单完整例子

    本文将深入探讨在Spring框架中如何管理事务,以“Spring 事务简单完整例子”为出发点,结合标签“spring,事务,jdbc事务”,我们将详细解释Spring事务管理的原理和实践。 首先,Spring提供了两种事务管理方式:编程...

    spring事务操作试验

    本文将深入探讨在"spring事务操作试验"中涉及的关键知识点,并结合提供的资源进行详细阐述。 首先,Spring事务管理的核心概念是ACID(原子性、一致性、隔离性和持久性),这是所有事务系统的基础。在Spring中,事务...

    Spring事务管理失效原因汇总

    标题“Spring事务管理失效原因汇总”指出了本文的核心内容是分析在使用Spring框架进行事务管理时可能遇到的问题及其原因。描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现...

    Spring事务详细讲解

    Spring事务详细讲解 在 Spring 框架中,事务管理扮演着非常重要的角色。Spring 声明式事务让我们从复杂的事务处理中得到解脱,使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要...

    实验 spring 声明事务

    实验 "Spring 声明事务" 是 Java 高级编程中的一个重要环节,旨在让学生掌握 Spring 框架中声明式事务管理的配置和使用。在实际应用中,事务管理是确保数据一致性、完整性和可靠性的关键组件。Spring 提供了声明式...

    spring学习事务源码

    本文将深入探讨Spring事务管理的源码,理解其背后的实现机制。 首先,Spring事务管理有两种主要模式:编程式事务管理和声明式事务管理。编程式事务管理通过调用`PlatformTransactionManager`接口提供的方法进行显式...

    SPRING事务机制DEMO

    Spring事务机制是Java开发中非常重要的一个概念,它在企业级应用中扮演着核心角色,确保数据的一致性和完整性。Spring提供了多种事务管理方式,包括编程式事务管理和声明式事务管理。在这篇DEMO中,我们将重点探讨...

    spring事务的底层实现流程图

    spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务...

    Spring事务操作示例(四种方式)

    Spring事务操作示例(四种方式),包含完整代码和数据库文件(基于MySQL,在项目sql文件夹中),可运行,学习Spring事务详见博客:http://blog.csdn.net/daijin888888/article/details/51822257

    Spring事务传播Demo.zip

    本篇将基于"Spring事务传播Demo"来深入探讨Spring事务管理和传播行为。 首先,我们需要理解什么是事务。在数据库操作中,事务是一组操作,这些操作要么全部执行,要么全部不执行,以确保数据的一致性和完整性。在...

    Spring事务传播机制.docx

    当我们在使用 Spring 所提供的事务功能时,如果是仅仅处理单个的事务,是比较容易把握事务的提交与回滚,不过一旦引入嵌套事务后,多个事务的回滚和提交就会变得复杂起来,各个事务之间是如何相互影响的,是一个值得...

Global site tag (gtag.js) - Google Analytics