Spring事务

编程式事务,Spring提供了一下两种事务管理的API

使用TransactionTemplate

直接使用一个PlatformTransactionManager实现

如果使用编程式事务管理,推荐使用TransactionTemplate(事务模板)

声明式事务:

 

 

Spring的声明式事务管理是通过AOP来实现的。使用时不需要修改原有的业务代码,只需要通过简单配置就可以追加事务控制功能

大多spring用户选择声明式事务管理。这是对程序代码影响最小的选择,因此也最符合非侵入式的概念。

 

注解实现声明式事务:没有用到AOP来进行显示的配置声明

步骤一:在applicationContext.xml文件中声明事务组件,开启事务注解扫面,示例如下:

<!—-声明事务管理器组件 -->
<bean id=”txManager”  class=”org.springframework.jdbc.datasource.DataSourceTransactionManager” >
    <property name=”dataSource” ref=”ds”/>
</bean>
<!—开启事务注解扫描-->
<tx:annotation-driven transaction-manager=”txManager” proxy-target-class=”true” />

 

transacton-manager指定事务管理器txManager ,需要根据数据库访问技术不同选择不同的实现,例如

JDBC ,MyBatis 技术选用DataSourceTransactionManager ,而Hibernate 技术则选用HibernateTransactionManager

 

注解实现声明式事务

步骤2

使用@Transactional注解声明事务,使用方法如下:

@Transactional(rollbackFor=ClassNotFoundException.class)
Public class DefaultFooService implements FooService{
       //@Transactional
       Public void insertFoo(Foo foo){}
       Public void updateFoo(Foo foo){}
}

@Transactional 注解标记可以用在类定义和方法定义前,方法的事务设置优于类级别的事务设置。

 

注解实现声明式事务:

@Transactional注解标记有一下属性在使用时可以根据需要做特殊设定

--propagation:设置事务传播

--isolation:设置事务隔离级别

--readOnly:设置为只读,还是可读写

--rollbackFor :设置遇到哪些异常必须回滚

--noRollbackFor :设置遇到哪些异常不回滚

 

注解实现声明式事务

@Transactional注解属性默认设置如下:

事务传播设置是:PROPAGATION_REQUIRED

事务隔离级别是:ISOLATION_DEFAULT

事务是  读/写

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

 

 

 

 

XML配置实现声明式事务:使用到AOP来进行配置声明

在applicationContext.xml文件中声明事务组件,配置事务作用的作用的范围及类型,示例代码如下:

<!— 声明事务管理组件-->
<bean id=”txManager” Class=”org.springframework.jdbc.datasource.DataSourceTransactionManager” >
     <property name=”dataSource” ref=”ds” />
</bean>
<!—XML配置声明事务范围及类型 -->
<tx:advice id=”txAdvice” transaction-manager=”txManager” >
       <tx:attributes>
            <tx:method name=”find*” read-only=”true”/>
            <tx:method name=”add*” propagation=”REQUIRED”/>
            <tx:method name=”update*” propagation=”REQUIRED”/>
            <tx:method name=”delete*” propagation=”REQUIRED”/>
       </tx:attributes> 
</tx:advice>
<aop:config proxy-target-class=”true”>使用的是代理类,而不是代理接口
      <aop:advisor advice-ref=”txAdvice” pointcut=”within(controller..*)” />指定目标组件(指定作用范围)
</aop:config>

 

 

 

事务回滚:

@Transactional默认情况下RuntimeException 异常将触发事务回滚,但是任何的Checked Exception将不触发事务回滚

常见的RuntimeException 和CheckedException 如图表所示:

RuntimeException: ArithmeticException , NullPointerException
,ClassCastException , NumberFormatException,
IndexOutOfBoundsException , NegativeArraySizeException
 
CheckedException:
ClassNotFoundException , NoSuchMethodExcepton
NoSuchFoundException , CloneNotSupportedException
IOException

对于CheckedException,需要手动地定义异常类型,才能实现事务回滚。

使用注解实现事务声明时,按如下方式指定异常

@Transactional(rollbackFor=ClassNotFoundException.class)

使用XML配置实现声明式事务,按如下方式指定异常

<tx:method name=”update*” propagation=”REQUIRED”
rollbackFor=”java.lang.ClassNotFoundException” />

当使用自定义异常时,异常类必须从RuntimeException集成才能自动回滚事务,否则需要指定事务回滚的异常类型

 

事务传播:

事务传播是指一个方法调用了另一个带有事务控制的方法,这种复杂情况就需要指定事务传播的处理方案,

Spring中事务的传播类型有如下几种

REQUIRED:支持当前事务 ,如果当前没有事务就新建一个事务,这是最常见的选择

SUPPORT:支持当前事务,如果当前没有事务,就以非事务方式执行

MANDATORY:支持当前事务,如果当前没有事务,就抛出异常

REQUIRES_NEW:新建事务,如果当前存在事务 ,就挂起

NOT_SUPPORTED:以非事务方式执行操作 ,如果当前存在事务 ,就挂起

NEVER:以非事务方式执行,如果当前存在事务就抛出异常

ENSTED: