Spring对于事务的管理

前言:Spring对于事务的管理提供了两种类型的事务管理。

  1. 编程式事务————通过Transaction Template手动管理事务,因为与业务代码具有一定的耦合性质,在做改动的时候势必会牵连到主业务,所以实际应用中很少使用。
  2. 声明式事务————使用XML配置声明式事务: 推荐使用(代码侵入性最小),实际是通过AOP实现。

1. 声明式事务

1.1 XML方式

其最大特点是与 Spring AOP 结合紧密,实际用的是AspectJ实现,可以充分利用切点表达式的强大支持,使得管理事务更加灵活。
是基于< tx> 和< aop>命名空间的声明式事务管理。

1.2 注解方式

@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的public 方法上。
@Transactional 注解只能应用到 public 可见度的方法上。如果你在 protected、private 或者package-visible 的方法上使用@Transactional 注解,它也不会报错,但是这个被注解的方法将不会展示已配置的事务设置【即不会生效】。

使用@Transactional注意点:

  • 如果在接口、实现类或方法上都指定了@Transactional 注解,则优先级顺序为方法>实现类>接口;

  • 建议只在实现类或实现类的方法上使用@Transactional,而不要在接口上使用,这是因为如果使用JDK代理机制(基于接口的代理)是没问题;而使用使用CGLIB代理(继承)机制时就会遇到问题,因为其使用基于类的代理而不是接口,这是因为接口上的@Transactional注解是“不能继承的”;

  • 在@Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class,可以让事物在遇到⾮运⾏时异常时也回滚。

@Transactional属性介绍

属性 类型 描述
value String 可选的限定描述符,指定使用的事务管理器
propagation enum: Propagation 可选的事务传播行为设置
isolation enum: Isolation 可选的事务隔离级别设置
readOnly boolean 读写或只读事务,默认读写
timeout int (in seconds granularity) 事务超时时间设置
rollbackFor Class对象数组,必须继承自Throwable 导致事务回滚的异常类数组
rollbackForClassName 类名数组,必须继承自Throwable 导致事务回滚的异常类名字数组
noRollbackFor Class对象数组,必须继承自Throwable 不会导致事务回滚的异常类数组
noRollbackForClassName 类名数组,必须继承自Throwable 不会导致事务回滚的异常类名字数组
  • propagation 代表事务的传播行为,默认值为 Propagation.REQUIRED

  • isolation :事务的隔离级别,默认值为 Isolation.DEFAULT

  • timeout :事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务

  • readOnly :指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true

  • rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型

  • noRollbackFor:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型

事务传播行为介绍
原文:https://blog.csdn.net/weixin_39625809/article/details/80707695
原文:https://blog.csdn.net/pml18710973036/article/details/58607148
传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。


举例有两个方法:

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
 methodB();
// do something
}
 
@Transactional(propagation = Propagation.REQUIRED)
public void methodB() {
    // do something
}

单独调用methodB方法时,因为当前上下文不存在事务,所以会开启一个新的事务。 
调用methodA方法时,因为当前上下文不存在事务,所以会开启一个新的事务。当执行到methodB时,methodB发现当前上下文有事务,因此就加入到当前事务中来。

隔离级别介绍
原文:https://zhuanlan.zhihu.com/p/112183409
原文:https://www.cnblogs.com/yangqiong1989/p/6882625.html
原文:https://blog.csdn.net/qq_37651267/article/details/92425172

事务失效
原文:https://baijiahao.baidu.com/s?id=1661650900351466294&wfr=spider&for=pc
原文:https://zhuanlan.zhihu.com/p/114461128
总结:

  • 在同一个类中,没有@Transactional注解的方法去调用有@Transactional注解

  • @Transactional 应用在非 public 修饰的方法上

  • @Transactional 注解属性 propagation 设置错误

  • 异常被你的 catch“吃了”导致@Transactional失效

  • 数据库引擎不支持事务

  • @Transactional 注解属性 rollbackFor 设置错误--抛出的异常为checked类型

rollbackFor 可以指定能够触发事务回滚的异常类型。Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor属性。
原文地址:https://www.cnblogs.com/itlihao/p/14958590.html