spring-事务xml配置详解

  1.     
  2. xml version="1.0" encoding="UTF-8"?>    
  3. <beans xmlns="http://www.springframework.org/schema/beans"    
  4.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  5.      xmlns:aop="http://www.springframework.org/schema/aop"    
  6.      xmlns:tx="http://www.springframework.org/schema/tx"    
  7.      xsi:schemaLocation="    
  8.      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd    
  9.      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd    
  10.      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">    
  11.       
  12.       
  13.   <bean id="fooService" class="x.y.service.DefaultFooService"/>    
  14.     
  15.     
  16.     
  17.   <tx:advice id="txAdvice" transaction-manager="txManager">    
  18.       
  19.   <tx:attributes>    
  20.         
  21.     <tx:method name="get*" read-only="true"/>    
  22.         
  23.     <tx:method name="*"/>    
  24.   tx:attributes>    
  25.   tx:advice>    
  26.       
  27.       
  28.   <aop:config>    
  29.       
  30.   <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>    
  31.       
  32.   <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>    
  33.   aop:config>    
  34.       
  35.       
  36.   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">    
  37.   <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>    
  38.   <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>    
  39.   <property name="username" value="scott"/>    
  40.   <property name="password" value="tiger"/>    
  41.   bean>    
  42.     
  43.       
  44.   <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    
  45.   <property name="dataSource" ref="dataSource"/>    
  46.   bean>     
  47.       

  1. beans> 
  2. Table 9.1.  有关的设置

    属性

    是否需要?

    默认值

    描述

    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'


    下面我们具体来看一下事务的传播性的几个值:

    REQUIRED:业务方法需要在一个容器里运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务。


    NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为他开启事务,如果方法在一个事务中被调用,该事务会被挂起,调用结束后,原先的事务会恢复执行。


    REQUIRESNEW:不管是否存在事务,该方法总汇为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务挂起,新的事务被创建。


    MANDATORY:该方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果在没有事务的环境下被调用,容器抛出例外。


    SUPPORTS:该方法在某个事务范围内被调用,则方法成为该事务的一部分。如果方法在该事务范围外被调用,该方法就在没有事务的环境下执行。


    NEVER:该方法绝对不能在事务范围内执行。如果在就抛例外。只有该方法没有关联到任何事务,才正常执行。


    NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务 拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

    到此为止基于XML的事务配置就算完成了。




    使用 @Transactional


    除了基于XML文件的声明式事务配置外,你也可以采用基于注解式的事务配置方法。直接在Java源代码中声明事务语义的做法让事务声明和将受其影响的代码距离更近了,而且一般来说不会有不恰当的耦合的风险,因为,使用事务性的代码几乎总是被部署在事务环境中。

    下面的例子很好地演示了 @Transactional 注解的易用性,随后解释其中的细节。先看看其中的类定义

    [java]  view plain  copy
    1. @Transactional    
    2. public class DefaultFooService implements FooService {    
    3.   Foo getFoo(String fooName);    
    4.   Foo getFoo(String fooName, String barName);    
    5.   void insertFoo(Foo foo);    
    6.   void updateFoo(Foo foo);    
    7. }    


    当我们使用注解式声明事务时,在XML中只需要一句话就ok了

    [html]  view plain  copy
    1. xml version="1.0" encoding="UTF-8"?>    
    2. <beans xmlns="http://www.springframework.org/schema/beans"    
    3.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    4.      xmlns:aop="http://www.springframework.org/schema/aop"    
    5.      xmlns:tx="http://www.springframework.org/schema/tx"    
    6.      xsi:schemaLocation="    
    7.      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd    
    8.      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd    
    9.      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">    
    10.       
    11.   <bean id="fooService" class="x.y.service.DefaultFooService"/>    
    12.    <tx:annotation-driven transaction-manager="txManager"/>    
    13.    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    
    14.    <property name="dataSource" ref="dataSource"/>    
    15.   bean>    
    16. beans>  

    我们知道 @Transactional 注解可以声明在类上,也可以声明在方法上。在大多数情况下,方法上的事务会首先执行

    例如: DefaultFooService 类在类的级别上被注解为只读事务,但是,这个类中的 updateFoo(Foo) 方法的 @Transactional 注解的事务设置将优先于类级别注解的事务设置。

    [java]  view plain  copy
    1. @Transactional(readOnly = true)    
    2. public class DefaultFooService implements FooService {    
    3.   public Foo getFoo(String fooName) {    
    4.     // do something    
    5.   }    
    6.     // these settings have precedence for this method    
    7.     @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)    
    8.     public void updateFoo(Foo foo) {    
    9.         // do something    
    10.            
    11.     }    
    12. }    


    @Transactional 有关的设置


    @Transactional 注解是用来指定接口、类或方法必须拥有事务语义的元数据。 如:当一个方法开始调用时就开启一个新的只读事务,并停止掉任何现存的事务”。 默认的 @Transactional 设置如下:

    事务传播设置是 PROPAGATION_REQUIRED

    事务隔离级别是 ISOLATION_DEFAULT

    事务是 读/

    事务超时默认是依赖于事务系统的,或者事务超时没有被支持。

    任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚

    这些默认的设置当然也是可以被改变的。 @Transactional 注解的各种属性设置总结如下:

     @Transactional 注解的属性

    属性

    类型

    描述

    propagation

    枚举型:Propagation

    可选的传播性设置

    isolation

    枚举型:Isolation

    可选的隔离性级别(默认值:ISOLATION_DEFAULT

    readOnly

    布尔型

    读写型事务 vs. 只读型事务

    timeout

    int型(以秒为单位)

    事务超时

    rollbackFor

    一组 Class 类的实例,必须是Throwable 的子类

    一组异常类,遇到时 必须 进行回滚。默认情况下checked exceptions不进行回滚,仅unchecked exceptions(即RuntimeException的子类)才进行事务回滚。

    rollbackForClassname

    一组 Class 类的名字,必须是Throwable的子类

    一组异常类名,遇到时 必须 进行回滚

    noRollbackFor

    一组 Class 类的实例,必须是Throwable 的子类

    一组异常类,遇到时 必须不 回滚。

    noRollbackForClassname

    一组 Class 类的名字,必须是Throwable 的子类

    一组异常类,遇到时 必须不 回滚

         在写代码的时候,不可能对事务的名字有个很清晰的认识,这里的名字是指会在事务监视器(比如WebLogic的事务管理器)或者日志输出中显示的名字, 对于声明式的事务设置,事务名字总是全限定名+"."+事务通知的类的方法名。比如BusinessService类的handlePayment(..)方法启动了一个事务,事务的名称是:

    com.foo.BusinessService.handlePayment








    使用 @Transactional


    除了基于XML文件的声明式事务配置外,你也可以采用基于注解式的事务配置方法。直接在Java源代码中声明事务语义的做法让事务声明和将受其影响的代码距离更近了,而且一般来说不会有不恰当的耦合的风险,因为,使用事务性的代码几乎总是被部署在事务环境中。

    下面的例子很好地演示了 @Transactional 注解的易用性,随后解释其中的细节。先看看其中的类定义

    @Transactional 有关的设置


    @Transactional 注解是用来指定接口、类或方法必须拥有事务语义的元数据。 如:当一个方法开始调用时就开启一个新的只读事务,并停止掉任何现存的事务”。 默认的 @Transactional 设置如下:

    事务传播设置是 PROPAGATION_REQUIRED

    事务隔离级别是 ISOLATION_DEFAULT

    事务是 读/

    事务超时默认是依赖于事务系统的,或者事务超时没有被支持。

    任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚

    这些默认的设置当然也是可以被改变的。 @Transactional 注解的各种属性设置总结如下:

     @Transactional 注解的属性

    属性

    类型

    描述

    propagation

    枚举型:Propagation

    可选的传播性设置

    isolation

    枚举型:Isolation

    可选的隔离性级别(默认值:ISOLATION_DEFAULT

    readOnly

    布尔型

    读写型事务 vs. 只读型事务

    timeout

    int型(以秒为单位)

    事务超时

    rollbackFor

    一组 Class 类的实例,必须是Throwable 的子类

    一组异常类,遇到时 必须 进行回滚。默认情况下checked exceptions不进行回滚,仅unchecked exceptions(即RuntimeException的子类)才进行事务回滚。

    rollbackForClassname

    一组 Class 类的名字,必须是Throwable的子类

    一组异常类名,遇到时 必须 进行回滚

    noRollbackFor

    一组 Class 类的实例,必须是Throwable 的子类

    一组异常类,遇到时 必须不 回滚。

    noRollbackForClassname

    一组 Class 类的名字,必须是Throwable 的子类

    一组异常类,遇到时 必须不 回滚

         在写代码的时候,不可能对事务的名字有个很清晰的认识,这里的名字是指会在事务监视器(比如WebLogic的事务管理器)或者日志输出中显示的名字, 对于声明式的事务设置,事务名字总是全限定名+"."+事务通知的类的方法名。比如BusinessService类的handlePayment(..)方法启动了一个事务,事务的名称是:

    com.foo.BusinessService.handlePayment


你可能感兴趣的:(spring)