Spring对于事务的管理
前言:Spring对于事务的管理提供了两种类型的事务管理。
- 编程式事务————通过Transaction Template手动管理事务,因为与业务代码具有一定的耦合性质,在做改动的时候势必会牵连到主业务,所以实际应用中很少使用。
- 声明式事务————使用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属性。