spring事务传播机制

7种事务的传播机制(可通过spring配置或注解来设置)

  REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。
  REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。
  SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。
  NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。
  MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。
  NEVER:无事务执行,如果当前有事务则抛出Exception。
  NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。
  注解配置时如:@Transactional(propagation=Propagation.REQUIRED)

注意

   事务调用只能作用于当前方法,所以对应的事务传播机制要在对应的方法上标明。

当前事务存在

   主方法可认为是产生当前事务的方法(此处不讨论多重调用的事务,原理是一样的);
   次方法则指带有对应传播机制的方法

传播机制 主方法异常 次方法异常
REQUIRED 全失败 全失败
REQUIRES_NEW 只有次方法的insert成功 全失败
SUPPORTS 全失败 全失败
NOT_SUPPORTED 只有次方法的insert成功 只有次方法的insert成功
MANDATORY 全失败 全失败
NEVER Existing transaction found Existing transaction found
NESTED 全失败 全失败

当前事务不存在

   当前事务不存在的情况下主方法的insert必然成功的,所以只需要考虑次方法是否成功了

传播机制 次方法异常
REQUIRED 失败
REQUIRES_NEW 失败
SUPPORTS 成功
NOT_SUPPORTED 成功
MANDATORY No existing transaction found
NEVER 成功
NESTED 失败

表格比较

   以上DEMO可以看出NESTED 和REQUIRED 作用非常类似,于是我继续查询资料得知NESTED 是增加了一个savepoint,我们可以使用try…catch…捕捉到异常来处理从而无需回滚之前的修改。

测试try_catch

   尝试除了never的次方法异常主方法使用try_catch时的情况

传播机制 次方法异常
REQUIRED Transaction rolled back because it has been marked as rollback-only
REQUIRES_NEW 只有主方法成功,次方法报错
SUPPORTS Transaction rolled back because it has been marked as rollback-only
NOT_SUPPORTED 全成功
MANDATORY Transaction rolled back because it has been marked as rollback-only
NESTED 主方法成功

总结

若存在当前事务

  1. 同一事务的REQUIRED 、SUPPORTS 、MANDATORY的次方法出现异常时,事务就会被标记为 rollback-only ;因此就算主方法catch到处理掉也只能回滚;
  2. 而同一事务的NESTED的次方法保存了savepoint,catch处理掉异常就能继续执行主方法了;
  3. REQUIRES_NEW、NOT_SUPPORTED的次方法则是挂起了当前事务,故他们就算出现异常处理掉就不会影响当前事务了;

可能使用同一事务的传播机制区别

  1. REQUIRED、SUPPORTS都能继承当前事务的,区别在于前者没有当前事务的时候会创建一个,后者则不会;
  2. MANDATORY则是要求必须要给它一个当前事务,它不会产生;

挂起当前事务两者的区别

  1. REQUIRES_NEW是会创建一个自己的新事务的;
  2. NOT_SUPPORTED则简单,它不用事务
NEVER不能存在当前事务且也不会创建自己的事务

测试代码GIT地址

你可能感兴趣的:(spring)