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: