`

事物管理,spring事物详解,spring @transactional

阅读更多
对于spring @transactional标签的使用时出现意料之外的错误,数据不同步。后来详细研究spring的事物机制和回滚的触发时机得到解决。以下资料收集于网络:


1.声明式事务配置
* 配置SessionFactory
* 配置事务管理器
* 事务的传播特性
* 那些类那些方法使用事务
2、编写业务逻辑方法
* 继承HibernateDaoSupport类,使用HibernateTemplate来持久化,HibernateTemplate是 Hibernate Session的轻量级封装
* 默认情况下运行期异常才会回滚(包括继承了RuntimeException子类),普通异常是不会滚的
* 编写业务逻辑方法时,最好将异常一直向上抛出,在表示层(struts)处理
* 关于事务边界的设置,通常设置到业务层,不要添加到Dao上 
3、了解事务的几种传播特性
1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启
2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常
7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务,
     则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行
4、Spring事务的隔离级别
1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
     另外四个与JDBC的隔离级别相对应
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
     这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
     它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
     除了防止脏读,不可重复读外,还避免了幻像读。   


  * 事务隔离:当前事务和其它事务的隔离的程度。例如,这个事务能否看到其他事务未提交的写数据?
  * 事务传播:通常在一个事务中执行的所有代码都会在这个事务中运行。但是,如果一个事务上下文已经存在,有几个选项可以指定一个事务性方法的执行行为:例如,简单地在现有的事务中继续运行(大多数情况);或者挂起现有事务,创建一个新的事务。Spring提供EJB CMT中常见的事务传播选项。
  * 事务超时: 事务在超时前能运行多久(自动被底层的事务基础设施回滚)。
  * 只读状态: 只读事务不修改任何数据。只读事务在某些情况下(例如当使用Hibernate时),是一种非常有用的优化。
* 回滚规则的概念比较重要:它使我们能够指定什么样的异常(和throwable)将导致自动回滚。我们在配置文件中声明式地指定,无须在Java代码中。同时,我们仍旧可以通过调用 TransactionStatus 的 setRollbackOnly() 方法编程式地回滚当前事务。通常,我们定义一条规则,声明 MyApplicationException 必须总是导致事务回滚。这种方式带来了显著的好处,它使你的业务对象不必依赖于事务设施。典型的例子是你不必在代码中导入Spring API,事务等。
* 在理解Spring的声明式事务管理方面最重要的概念是:Spring的事务管理是通过AOP代理实现的。其中的事务通知由元数据(目前基于XML或注解)驱动。代理对象与事务元数据结合产生了一个AOP代理,它使用一个PlatformTransactionManager实现品配合TransactionInterceptor,在方法调用前后实施事务。
*
* Spring框架的事务基础架构代码将默认地 只 在抛出运行时和unchecked exceptions时才标识事务回滚。 也就是说,当抛出一个 RuntimeException 或其子类例的实例时。(Errors 也一样 - 默认地 - 标识事务回滚。)从事务方法中抛出的Checked exceptions将 不 被标识进行事务回滚。
* 就是这些默认的设置;严格规定了哪些 Exception 类型将被标识进行事务回滚。
  默认的 <tx:advice/> 设置如下:
  * 事务传播设置是 REQUIRED
  * 隔离级别是 DEFAULT
  * 事务是 读/写
  * 事务超时默认是依赖于事务系统的,或者事务超时没有被支持。
  * 任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚




  Table?9.1.?<tx:method/> 有关的设置
属性是否需要?默认值描述name是?   与事务属性关联的方法名。通配符(*)可以用来指定一批关联到相同的事务属性的方法。 如:'get*'、'handle*'、'on*Event'等等。 propagation不REQUIRED事务传播行为isolation不DEFAULT事务隔离级别timeout不-1事务超时的时间(以秒为单位)read-only不false事务是否只读?rollback-for不?   将被触发进行回滚的 Exception(s);以逗号分开。 如:'com.foo.MyBusinessException,ServletException' no-rollback-for不?   不 被触发进行回滚的 Exception(s);以逗号分开。 如:'com.foo.MyBusinessException,ServletException'


事务回滚陷阱

清单 1. 没有回滚支持

@Transactional(propagation=Propagation.REQUIRED)
public TradeData placeTrade(TradeData trade) throws Exception {
   try {
      insertTrade(trade);
      updateAcct(trade);
      return trade;
   } catch (Exception up) {
      //log the error
      throw up;
   }
}


假设帐户中没有足够的资金来购买需要的股票,或者还没有准备购买或出售股票,并抛出了一个受控异常(例如 FundsNotAvailableException),那么交易订单会保存在数据库中吗?还是整个逻辑工作单元将执行回滚?答案出乎意料:根据受控异常(不管是在 Spring Framework 中还是在 EJB 中),事务会提交它还未提交的所有工作。使用清单 13,这意味着,如果在执行 updateAcct() 方法期间抛出受控异常,就会保存交易订单,但不会更新帐户来反映交易情况。

这可能是在使用事务时出现的主要数据完整性和一致性问题了。运行时异常(即非受控异常)自动强制执行整个逻辑工作单元的回滚,但受控异常不会。因此,清单 13 中的代码从事务角度来说毫无用处;尽管看上去它使用事务来维护原子性和一致性,但事实上并没有。

尽管这种行为看起来很奇怪,但这样做自有它的道理。首先,不是所有受控异常都是不好的;它们可用于事件通知或根据某些条件重定向处理。但更重要的是,应用程序代码会对某些类型的受控异常采取纠正操作,从而使事务全部完成。例如,考虑下面一种场景:您正在为在线书籍零售商编写代码。要完成图书的订单,您需要将电子邮件形式的确认函作为订单处理的一部分发送。如果电子邮件服务器关闭,您将发送某种形式的 SMTP 受控异常,表示邮件无法发送。如果受控异常引起自动回滚,整个图书订单就会由于电子邮件服务器的关闭全部回滚。通过禁止自动回滚受控异常,您可以捕获该异常并执行某种纠正操作(如向挂起队列发送消息),然后提交剩余的订单。

使用 Declarative 事务模式(本系列的第 2 部分将进行更加详细的描述)时,必须指定容器或框架应该如何处理受控异常。在 Spring Framework 中,通过 @Transactional 注释中的 rollbackFor 参数进行指定,如清单 2所示:


清单 2. 添加事务回滚支持 — Spring

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public TradeData placeTrade(TradeData trade) throws Exception {
   try {
      insertTrade(trade);
      updateAcct(trade);
      return trade;
   } catch (Exception up) {
      //log the error
      throw up;
   }
}


注意,@Transactional 注释中使用了 rollbackFor 参数。这个参数接受一个单一异常类或一组异常类,您也可以使用 rollbackForClassName 参数将异常的名称指定为 Java String 类型。还可以使用此属性的相反形式(noRollbackFor)指定除某些异常以外的所有异常应该强制回滚。通常大多数开发人员指定 Exception.class 作为值,表示该方法中的所有异常应该强制回滚。


受控异常就是checked Exception ,这些异常在你写代码时候必须用try{}catch语句抓住,或者throw抛出,不然代码编译时候就通不过。比如IOException ,SqlException,FileNotFoundExcption等等,
而运行时异常是你写代码的时候不需要catch,或者throw就可以通过编译的异常,一般由于程序员的错误引起的,比如NullPointException异常,数组越界异常,这些都是没法在 try catch中恢复的,异常需要程序员细心检查出错误。
而error是继承throwable接口,但和异常是不同的概念,error基本上就是jvm运行时内存耗尽,系统崩溃等等重大的错误,级别高于Exception,而且没法恢复。



另见:
http://www.ibm.com/developerworks/cn/java/j-ts1.html
http://www.javaworld.com.tw/confluence/display/opensrc/Spring
http://www.redsaga.com/spring_ref/2.0/html/transaction.html#transaction-declarative


分享到:
评论
1 楼 HappyVeryGood 2013-07-27  
“运行时异常(即非受控异常)自动强制执行整个逻辑工作单元的回滚,但受控异常不会。”

这里的受控异常和非受控异常,不明白是什么意思?楼主可以解释下不。。
我看上面的例子,是这样理解的不过感觉我理解的不对:
异常被捕获了,就是受控异常。否则就是非受控异常。。
但是很显然,上例捕获后有直接抛出去了,我感觉就跟没捕获一样的效果。。不解呀,望楼主解答,,,

相关推荐

    Spring @Transactional工作原理详解

    在Spring框架中,`@Transactional`注解是一个强大的工具,用于声明式地管理事务。它使得开发者无需显式地在代码中控制事务的开始、提交和回滚,从而提高了代码的可读性和可维护性。下面我们将深入探讨`@...

    spring的annotation-driven配置事务管理器详解 (多数据源配置

    Spring 的 Annotation-Driven 配置事务管理器详解(多数据源配置) Spring 框架提供了强大的事务管理机制,通过使用 Annotation-Driven 配置,可以方便地管理事务。在多数据源配置中,spring 的 Annotation-Driven...

    Spring事务详解

    而声明式事务管理则是基于AOP(面向切面编程)实现,通过在方法上添加@Transactional注解,让Spring自动进行事务管理,这种方式更为简单且易于维护。 在Spring中,我们可以选择不同的事务传播行为,例如PROPAGATION...

    Hibernate缓存与spring事务详解

    **标题:“Hibernate缓存与Spring事务详解”** 在IT领域,尤其是Java开发中,Hibernate作为一款流行的ORM(对象关系映射)框架,极大地简化了数据库操作。而Spring框架则以其全面的功能,包括依赖注入、AOP(面向切...

    Spring事务优缺点及使用详解.docx

    【Spring 事务管理详解】 一、事务简介 事务是数据库操作的基本单位,它确保一组SQL语句要么全部成功,要么全部失败,以维护数据的一致性。在MySQL中,事务通常涉及INSERT、UPDATE、SELECT和DELETE等操作。当操作...

    spring事务详解

    Spring事务详解 Spring框架的事务管理功能是Java企业级开发中的重要组成部分,它将事务管理从具体的业务逻辑和数据访问逻辑中独立出来,实现了关注点分离。这种分离不仅降低了事务管理的复杂性,而且增强了代码的可...

    Spring中事务的传播属性详解

    ### Spring中事务的传播属性详解 #### 一、引言 在使用Spring框架进行应用程序开发时,事务管理是一项非常重要的特性。Spring提供了两种事务管理方式:编程式事务管理和声明式事务管理。其中,声明式事务管理因其...

    spring几种事务配置详解【精】

    在Spring框架中,事务管理是核心功能之一,它为应用程序提供了强大的事务控制能力,确保了数据的一致性和完整性。本文将深入探讨Spring中的几种事务配置方式,帮助开发者更好地理解和运用。 1. **编程式事务管理** ...

    spring事务配置详解

    在类或方法上添加`@Transactional`,Spring AOP会根据注解的属性来管理事务。 **第三种方式:基于XML的声明式事务管理** 在Spring的配置文件中,使用`&lt;tx:advice&gt;`和`&lt;aop:config&gt;`元素来定义事务策略和切面。 ```...

    spring事务管理.rar

    《Spring事务管理详解》 在Java企业级应用开发中,数据一致性是至关重要的,而Spring框架的事务管理机制就是为了解决这个问题。本教程将深入探讨Spring中的事务管理,包括其核心概念、配置方式以及实战应用。 首先...

    SpringBoot事务和Spring事务详讲

    ### Spring Boot 与 Spring 事务详解 #### 一、引言 在现代企业级应用程序开发中,事务管理是一项至关重要的技术。它确保了一系列操作能够作为一个整体成功或失败,从而维护了数据的一致性和完整性。Spring 框架...

    10-Spring-事务管理1

    Spring通过在方法或类上使用`@Transactional`注解来实现声明式事务管理。 3. **Spring的事务管理器** Spring 提供了多种事务管理器,如`DataSourceTransactionManager`用于处理基于JDBC的数据源事务,`...

    spring事务管理

    ### Spring事务管理详解 #### 一、事务管理基础概念 在深入探讨Spring事务管理之前,我们需要先理解什么是事务。事务可以被定义为一系列的操作集合,这些操作作为一个整体被提交或回滚。简单来说,事务就是一个不...

    Spring事务处理原理步骤详解

    Spring事务处理原理步骤详解是指在Spring框架中实现事务处理的整个过程,它涉及到事务处理的实现、事务处理原理和事务管理器的配置等几个方面。下面是Spring事务处理原理步骤详解的知识点总结: 一、事务处理实现 ...

    spring高级编程详解

    ### Spring高级编程详解:深入理解声明式事务管理 #### 一、引言 在现代软件开发中,事务处理是确保数据一致性和完整性的重要手段之一。传统的事务管理方式往往需要开发者手动编写大量的代码来处理诸如获取数据库...

    详解Spring配置事务的五种方式

    在Spring框架中,事务管理是核心功能之一,它确保了数据操作的一致性和完整性。本文将详细介绍Spring配置事务的五种方式,以便开发者们更好地理解和应用。 首先,Spring配置事务通常涉及三个关键组件: 1. **...

Global site tag (gtag.js) - Google Analytics