Spring中声明式事务

声明式事务:基于Spring AOP,通过注解或XML配置实现,有助于用户将操作与事务规则进行解耦。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

本文主要对基于注解的方式叙述。

事务注解:@Transactional,加此注解看作一个事务,要么都成功要么都失败。

纯注解模式下实现事务只需要把注解驱动的注解形式@EnableTransactionManagement 加在Spring的配置类上就可以了。

@Transactional注解用于两种场景:

  • 标于类上:表示当前类以及其下无限级子类中所有pubilc方法将被spring自动加上事务。
    一般不推荐使用,事务控制的粒度太大。

  • 标于方法上:仅对该方法。
    当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。

  • 标于接口上:表示接口的实现类中所有public方法都被spring自动加上事务
    不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效。

@Transactional 只能被应用到public方法上,对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能。

Spring事务失效场景

Spring中声明式事务_第1张图片最常见的:既添加了@Transactional 注解,方法里却又添加了catch语句对业务进行异常捕获,都把异常“吃”掉了,Spring自然不知道这里有错,更不会主动去回滚数据。

 

参数

参数 描述
value 指定事务管理器的bean名称,如果容器中有多事务管理器PlatformTransactionManager,那么得告诉spring,当前配置需要使用哪个事务管理器
transactionManager 同value,value和transactionManager选配一个就行,也可以为空,如果为空,默认会从容器中按照类型查找一个事务管理器bean
propagation 事务的传播属性
isolation 事务的隔离级别,就是制定数据库的隔离级别,数据库隔离级别大家知道么?不知道的可以去补一下
timeout 事务执行的超时时间(秒)。执行一个方法,有问题,可能最多只能等5秒, 5秒后,还没有执行完毕,就弹出一个超时异常。
readOnly 是否是只读事务,比如某个方法中只有查询操作,可以指定事务是只读的,设置了这个参数,数据库可能会做一些性能优化,提升查询速度
rollbackFor 定义零(0)个或更多异常类,这些异常类必须是Throwable的子类,当方法抛出这些异常及其子类异常的时候,spring会让事务回滚,如果不配做,那么默认会在 RuntimeException 或者 Error 情况下,事务才会回滚
rollbackForClassName 同 rollbackFor,只是这个地方使用的是类名
noRollbackFor 定义零(0)个或更多异常类,这些异常类必须是Throwable的子类,当方法抛出这些异常的时候,事务不会回滚
noRollbackForClassName 同 noRollbackFor,只是这个地方使用的是类名

事务的回滚和不回滚

(1)rollbackFor:参数为class类型的数组,定义哪些异常时回滚;

(2)rollbackForClassName:参数为字符串类型的数组,定义哪些异常时回滚;

(3)noRollbackFor:参数为class类型的数组,定义哪些异常时不回滚;

(4)noRollbackForClassName:参数为字符串类型的数组,定义哪些异常时不回滚。

@Transactional 默认只能回滚RuntimeException和RuntimeException下面的子类抛出的异常,不能回滚Exception异常;如果需要支持回滚Exception异常,需要显示的指明。
如:@Transactional(rollbackFor = Exception.class);

rollbackFor 回滚(预提交) --------》 Exception可替换

  • Exception 表示:遇到错误就回滚;
  • ServiceException 表示:当ServiceException 失败时,才回滚
  • ...

显示的指定rollbackFor注解属性,即使rollbackFor有默认值,但阿里巴巴开发者规范中,还是要求开发者重新指定该参数,因为如果使用默认值,一旦程序抛出了非运行时的其他Exception,事务不会回滚,这会出现很大的bug;

在数据库中操作时:

将数据库变更当作一个事务,整个处理操作完成后,才进行数据库操作,只要里面有一个错误,就失败了。

尤其涉及到多个表的数据库操作时,一定要使用这个注解!!!

 

你可能感兴趣的:(Java,java,spring)