Spring事务传播机制面试题

2021-11-16 14:25:02 浏览数 (2)

事务传播,就是两个事务进行调用时候,这个事务如何运行,而spring定义了7种传播行为,我们分别讲解

PROPAGATION_REQUIRED

如果存在一个事务,则支持当前事务,如果没有事务则开启一个新的事务,如下面方法,单独调用B方法时候,因为上下文不存事务,则开启一个新的事务,但是如果A方法调用B方的时候,由于方法A存在事务,则方法B加入当前事务也就是方法A的事物

代码语言:javascript复制
@Transactional(propagation = Propagation.REQUIRED)
 public  void  methodA(){
//todo
     methodB();
//todo
 }
 @Transactional(propagation = Propagation.REQUIRED)
 public  void  methodB(){
//todo
 }

PROPAGATION_SUPPORTS

如果存在一个事物,支持当前事务,如果没有事务,则以非事务执行,如下面,如果单独调用B方法,则以非事务执行,但是如果方法A调用方法B则加入方法A事务中

代码语言:javascript复制
@Transactional(propagation = Propagation.REQUIRED)
 public  void  methodA(){
//todo
        methodB();
//todo
  }
   @Transactional(propagation = Propagation.SUPPORTS)
  public  void  methodB(){
//todo
 }

PROPAGATION_MANDATORY

该方法必须以事务中运行,如果当前事务不存在则抛出异常,如下如,当单独调用方法B,则抛出异常,必须让方法A调用方法B

代码语言:javascript复制
@Transactional(propagation = Propagation.REQUIRED)
public  void  methodA(){
//todo
    methodB();
//todo
}
@Transactional(propagation = Propagation.MANDATORY)
public  void  methodB(){
//todo
}

PROPAGATION_REQUIRES_NEW

他会开启一个新的事务,如果已经存在一个事务,则挂起这个存在的事务,比如下面,如果单独调用方法B他会自己开启一个事务,但是如果方法A调用方法B,则挂起方法A的事务,方法B开启一个新的事物,也就是说他们两个事务是不相关的,再比如,当方法A调用完方法B之后,方法A失败了,只会回滚方法A执行的内容,而不会影响方法B

代码语言:javascript复制
@Transactional(propagation = Propagation.REQUIRED)
public  void  methodA(){
//todo
    methodB();
//todo
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public  void  methodB(){
//todo
}

PROPAGATION_NOT_SUPPORTED

他是以非事务运行,如果存在事务中,就会挂起这个事务,以非事务运行,比如下面两个方法,方法A调用方法B的时候方法B以非事务运行,而单独调用方法B也是以非事务运行

代码语言:javascript复制
@Transactional(propagation = Propagation.REQUIRED)
public  void  methodA(){
//todo
    methodB();
//todo
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public  void  methodB(){
//todo
}

PROPAGATION_NEVER

他总是以非事务运行,如果存在事务运行就会报错

PROPAGATION_NESTED

是一个嵌套事务,如果没有事务则会开启一个事物,但是如果存在事务,就会嵌套在这个事务中并且开启一个事务,比如,方法B单独调用就会开启一个事物,但是如果方法A开启事物,调用方法B开启一个嵌套事务,当外层方法A失败的时候,会回滚方法B的内容,但是如果方法B失败仅仅回滚自己内部的内容,不会影响外层事物

代码语言:javascript复制
@Transactional(propagation = Propagation.REQUIRED)
public  void  methodA(){
//todo
    methodB();
//todo
}
@Transactional(propagation = Propagation.NESTED)
public  void  methodB(){
//todo
}

其中比较容易混淆的PROPAGATION_NESTED和PROPAGATION_REQUIRES_NEW,两个都是不存在事务,就开启一个新的事务,但是PROPAGATION_NESTED开启的事务,外层事物会影响内层事务,内层事务是外层事务的一个子事务,而PROPAGATION_REQUIRES_NEW就行开启了两个独立的事务,两个事务互不影响‍

0 人点赞