spring对事务的配置

接下来我将给你们介绍spring事务配置的两种方式:html

1.基于XML的事务配置。2.基于注解方式的事务配置。java

前言:在咱们详细介绍spring的两种声明式事务管理以前,咱们须要先理解这些概念

1)spring的事务管理是经过Aop的方式来实现;
2)声明式事务是spring对事务管理的最经常使用的方式,由于这种方式对代码的影响最小,所以也就符合非侵入式的轻量级的容器的概念;
3)咱们须要理解事务的概念,这里再也不给出详细说明。

正文:

1.基于XMl的事务配置

如今假设咱们有这样一个接口:
[java]  view plain  copy
 
  1. package x.y.service;    
  2. public interface FooService {    
  3.   Foo getFoo(String fooName);    
  4.   Foo getFoo(String fooName, String barName);    
  5.   void insertFoo(Foo foo);    
  6.   void updateFoo(Foo foo);    
  7. }   
[java]  view plain  copy
 
  1. </pre>对应于这个接口有一个实现类以下:<pre name="code" class="java">package x.y.service;    
  2. public class DefaultFooService implements FooService {    
  3.   public Foo getFoo(String fooName) {    
  4.     throw new UnsupportedOperationException();    
  5.   }    
  6.   public Foo getFoo(String fooName, String barName) {    
  7.     throw new UnsupportedOperationException();    
  8.   }    
  9.   public void insertFoo(Foo foo) {    
  10.     throw new UnsupportedOperationException();    
  11.   }    
  12.   public void updateFoo(Foo foo) {    
  13.     throw new UnsupportedOperationException();    
  14.   }}    
注:上述两端代码是对应于业务层的。咱们平时配置事务也最好在业务层进行配置。
 
接下来咱们看一下spring 的配置文件中须要咱们配置什么吧
[html]  view plain  copy
 
  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 -->    
  48. </beans>    
 
如今我通俗的把上面的配置讲解一下:
首先咱们应该要把服务对象'fooService' 声明成一个bean咱们要把一个服务对象('fooService' bean)作成事务性的。
咱们就应该首先在声明一个事务管理的建议,用什么来管理,spring给咱们提供了事务封装,这个就封装在了<tx:advice/>中,
这个事务建议给咱们提供了一个transaction-manager属性,用他能够指定咱们用谁来管理咱们的事务。咱们上边的例子用的
为一个指向 PlatformTransactionManager bean的名字(这里指 'txManager'), 该bean将会真正管理事务。上面用的事务
管理类是用的jdbc中提供的事务管理,固然这里也能够指定为hibernate管理。固然了,无论用那个类来管理咱们的事务,都
不要忘记了提供咱们的datasource属性,由于事务管理也须要这里面的信息。咱们声明好事务建议,也指定好了具体用哪一个
类来管理了,下面咱们的任务就是要把咱们定义好的这些利用AOP把咱们的事务管理织入到咱们的业务逻辑里面
<aop:config/> 的定义, 它确保由 'txAdvice'  bean定义的事务通知在应用中合适的点被执行。 
首先咱们定义了 一个切面,它匹配 FooService 接口定义的全部操做, 
咱们把该切面叫作 'fooServiceOperation'。<aop:pointcut/> 元素定义是AspectJ的切面表示法,
上述表示x.y.service.FooService包下的任意方法。而后咱们用一个通知器(advisor)把这个切面与 'txAdvice' 绑定在一块儿,
 表示当 'fooServiceOperation' 执行时,'txAdvice' 定义的通知逻辑将被执行。大致流程就是这样的了。

<tx:advice/> 有关的设置spring

经过 <tx:advice/> 标签来指定不一样的事务性设置。默认的 <tx:advice/> 设置以下:express

事务传播设置是 REQUIREDapache

隔离级别是DEFAULToracle

事务是 读/ide

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

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

这些默认的设置固然也是能够被改变的。 <tx:advice/> 和 <tx:attributes/> 标签里的 <tx:method/> 各类属性设置总结以下:spa

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

接下来我将给你们介绍spring事务配置的两种方式:

1.基于XML的事务配置。2.基于注解方式的事务配置。

前言:在咱们详细介绍spring的两种声明式事务管理以前,咱们须要先理解这些概念

1)spring的事务管理是经过Aop的方式来实现;
2)声明式事务是spring对事务管理的最经常使用的方式,由于这种方式对代码的影响最小,所以也就符合非侵入式的轻量级的容器的概念;
3)咱们须要理解事务的概念,这里再也不给出详细说明。

正文:

1.基于XMl的事务配置

如今假设咱们有这样一个接口:
[java]  view plain  copy
 
  1. package x.y.service;    
  2. public interface FooService {    
  3.   Foo getFoo(String fooName);    
  4.   Foo getFoo(String fooName, String barName);    
  5.   void insertFoo(Foo foo);    
  6.   void updateFoo(Foo foo);    
  7. }   
[java]  view plain  copy
 
  1. </pre>对应于这个接口有一个实现类以下:<pre name="code" class="java">package x.y.service;    
  2. public class DefaultFooService implements FooService {    
  3.   public Foo getFoo(String fooName) {    
  4.     throw new UnsupportedOperationException();    
  5.   }    
  6.   public Foo getFoo(String fooName, String barName) {    
  7.     throw new UnsupportedOperationException();    
  8.   }    
  9.   public void insertFoo(Foo foo) {    
  10.     throw new UnsupportedOperationException();    
  11.   }    
  12.   public void updateFoo(Foo foo) {    
  13.     throw new UnsupportedOperationException();    
  14.   }}    
注:上述两端代码是对应于业务层的。咱们平时配置事务也最好在业务层进行配置。
 
接下来咱们看一下spring 的配置文件中须要咱们配置什么吧
[html]  view plain  copy
 
  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 -->    
  48. </beans>    
 
如今我通俗的把上面的配置讲解一下:
首先咱们应该要把服务对象'fooService' 声明成一个bean咱们要把一个服务对象('fooService' bean)作成事务性的。
咱们就应该首先在声明一个事务管理的建议,用什么来管理,spring给咱们提供了事务封装,这个就封装在了<tx:advice/>中,
这个事务建议给咱们提供了一个transaction-manager属性,用他能够指定咱们用谁来管理咱们的事务。咱们上边的例子用的
为一个指向 PlatformTransactionManager bean的名字(这里指 'txManager'), 该bean将会真正管理事务。上面用的事务
管理类是用的jdbc中提供的事务管理,固然这里也能够指定为hibernate管理。固然了,无论用那个类来管理咱们的事务,都
不要忘记了提供咱们的datasource属性,由于事务管理也须要这里面的信息。咱们声明好事务建议,也指定好了具体用哪一个
类来管理了,下面咱们的任务就是要把咱们定义好的这些利用AOP把咱们的事务管理织入到咱们的业务逻辑里面
<aop:config/> 的定义, 它确保由 'txAdvice'  bean定义的事务通知在应用中合适的点被执行。 
首先咱们定义了 一个切面,它匹配 FooService 接口定义的全部操做, 
咱们把该切面叫作 'fooServiceOperation'。<aop:pointcut/> 元素定义是AspectJ的切面表示法,
上述表示x.y.service.FooService包下的任意方法。而后咱们用一个通知器(advisor)把这个切面与 'txAdvice' 绑定在一块儿,
 表示当 'fooServiceOperation' 执行时,'txAdvice' 定义的通知逻辑将被执行。大致流程就是这样的了。

<tx:advice/> 有关的设置

经过 <tx:advice/> 标签来指定不一样的事务性设置。默认的 <tx:advice/> 设置以下:

事务传播设置是 REQUIRED

隔离级别是DEFAULT

事务是 读/

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

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

这些默认的设置固然也是能够被改变的。 <tx:advice/> 和 <tx:attributes/> 标签里的 <tx:method/> 各类属性设置总结以下:

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

相关文章
相关标签/搜索