spring-事务xml配置详解

  1. <!-- from the file 'context.xml' -->    
  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.   <!-- 首先我们要把服务对象fooService声明成一个bean -->    
  13.   <bean id="fooService" class="x.y.service.DefaultFooService"/>    
  14.     
  15.   <!-- 然后是声明一个事物建议tx:advice,spring为我们提供了事物的封装,这个就是封装在了<tx:advice/>中 -->  
  16.   <!-- <tx:advice/>有一个transaction-manager属性,我们可以用它来指定我们的事物由谁来管理。 -->  
  17.   <tx:advice id="txAdvice" transaction-manager="txManager">    
  18.   <!-- 配置这个事务建议的属性 -->    
  19.   <tx:attributes>    
  20.     <!-- 指定所有get开头的方法执行在只读事务上下文中 -->    
  21.     <tx:method name="get*" read-only="true"/>    
  22.     <!-- 其余方法执行在默认的读写上下文中 -->    
  23.     <tx:method name="*"/>    
  24.   </tx:attributes>    
  25.   </tx:advice>    
  26.       
  27.   <!-- 我们定义一个切面,它匹配FooService接口定义的所有操作 -->    
  28.   <aop:config>    
  29.     <!-- <aop:pointcut/>元素定义AspectJ的切面表示法,这里是表示x.y.service.FooService包下的任意方法。 -->  
  30.   <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>    
  31.     <!-- 然后我们用一个通知器:<aop:advisor/>把这个切面和tx:advice绑定在一起,表示当这个切面:fooServiceOperation执行时tx:advice定义的通知逻辑将被执行 -->  
  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.   <!-- other <bean/> definitions here -->    

  1. </beans> 
  2. 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'


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

    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


  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值