目录
文章目录
Spring事务的传播
事务的传播七种行为/模式/机制
行为 | 解释 | 对应的注解使用 |
---|---|---|
PROPAGATION_REQUIRED | (默认)以事务运行,当前有事务则加入事务,无事务则创建事务 | @Transactional(propagation = Propagation.REQUIRED) |
PROPAGATION_SUPPORTS | 支持事务运行,如果没有事务则以非事务运行(实际应用上与不加注解没什么去呗,实际上还是有点区别) | @Transactional(propagation = Propagation.SUPPORTS) |
PROPAGATION_MANDATORY | 用于标识一个方法必须开启事务使用,否则抛出异常。此行为在一个方法强烈需要使用事务管理的时候使用。由周围事务驱动,本身并不创建事务 | @Transactional(propagation = Propagation.MANDATORY) |
PROPAGATION_REQUIRES_NEW | 创建一个新事务,挂起当前事务,当执行完成NEW事务后返回当前事务,当前事务如果回滚不影响NEW事务的提交,如果NEW事务抛出异常,当前事务方法没有正确捕获异常,则全部回滚 | @Transactional(propagation = Propagation.REQUIRES_NEW) |
PROPAGATION_NOT_SUPPORTED | 已非事务运行,当前存在事务则挂起 | @Transactional(propagation = Propagation.NOT_SUPPORTED) |
PROPAGATION_NEVER | 以非实物运行,如果存在事务则抛出异常 | @Transactional(propagation = Propagation.NEVER) |
PROPAGATION_NESTED | 创建一个新事务,当前事务存在时则加入当前事务作为一个嵌套事务。 | @Transactional(propagation = Propagation.NESTED) |
嵌套事务的解释(PROPAGATION_NESTED)
- 当前存在事务的时候,创建一个子事务运行在当前事务中。
- 子事务回滚的时候,当前事务的方法如果正确捕获异常,则当前事务可以正常提交。
serviceA{
@Transactional(propagation = Propagation.REQUIRED)
public void A(){
try{
serviceB();
}catch(e){
}
}
}
serviceB{
@Transactional(propagation = Propagation.NESTED)
public void B(){}
}
- 当子事务会随着当前事务一起提交
- 当前事务发生回滚,则子事务一起回滚
Spring事务和代理模式的关系
Springboot默认开启了
CglibProxy
查看Spring的bean当前使用的代理模式
默认不使用代理的,当类或者类中某个方法加入事务的时候会使用代理
- AopUtils.isAopProxy(service);
- AopUtils.isCglibProxy(service);
- AopUtils.isJdkDynamicProxy(service);
事务生效场景
加了事务注解的方法,理论上只有一种情况生效,那就是通过代理类调用事务方法
AopContext.currentProxy()获取当前类的代理类
代码:
serviceA{
@Transactional(propagation = Propagation.REQUIRED)
public void A(){
try{
serviceB();
}catch(e){
}
}
public void AA(){
}
}
serviceB{
@Transactional(propagation = Propagation.REQUIRED)
public void B(){}
public void BB(){}
}
以下调用过程及事务是否生效
- 两个方法都有事务
- 由于AA方法没有开启事物,调用A方法也没有通过代理,所以两个方法都没有事务