Spring 事务传播机制以及隔离级别

前言

众所周知,Spring是实现事务配置是通过注解 Transactional 来实现的,但是注解中含有多个参数, 其中rollbackFor、propagation、isolation,这个三个参数算是比较常用的,本文主要讲解一下以上参数:

异常捕获rollbackFor:

  1. 关于异常的介绍,推荐博文: https://blog.csdn.net/zhangerqing/article/details/8248186
  2. Spring框架的事务管理默认地只在发生不受控异常(RunTimeException 以及其子类)时会进行事务回滚,但是当方法运行时抛出受控异常(非RunTimeException 以及其子类)时 transactionManager并不会回滚,
  3. rollbackFor 用于捕获相应异常,并且进行事务回滚,默认是RunTimeException ,但是Alibaba 开发手册中提醒我们指定 所要捕获的异常类型,用于事务控制,例如捕获所有异常配置:
// 所有异常都会回滚
@Transactional(rollbackFor = Exception.class)

事务传播机制propagation:

  1. Spring的传播机制有7种:
类型 参数名 解释
支持当前事务 Propagation. REQUIRED(默认) 如果当前没有事务,就新建一个事务,如果有事务,就加入其中
支持当前事务 Propagation.SUPPORTS 支持当前事务,如果没有事务,则以非事务的形式执行
支持当前事务 Propagation.MANDATORY 支持当前事务,如果没有事务,就抛出异常
不支持当前事务 Propagation.REQUIRES_NEW 新建事务,如果存在事务,就将事务挂起,新建一个事务
不支持当前事务 Propagation.NOT_SUPPORTED 以非事务的方式执行,当前存在事务,就把当前事务挂起
不支持当前事务 Propagation.NEVER 以非事务的方式执行,如果当前有事务,则抛出异常
事务嵌套 Propagation.NESTED 如果当前存在事务,则在嵌套事务中执行;如果当前没有事务,则执行与Propagation. REQUIRED类似的操作
  1. 其中常用的事务传播机制有:
    Propagation. REQUIRED:默认
    Propagation.NOT_SUPPORTED:用于新业务不影响主体业务逻辑,及时业务执行异常也不会影响主体业务逻辑
    Propagation.REQUIRES_NEW:一般用于记录业务日志

  2. Propagation.NESTED 是较为难理解的事务隔离: 当前存在事务时,会发生嵌套事务,会在子方法执行前,加入SavePoint, 当子事务回滚时,会回到当前点,主体逻辑不会回滚,只有当主业务提交之后,才会全部提交。

  3. 注意Spring 事务控制是根据捕获异常信息来处理的,如在业务中捕获了异常会造成事务回滚失败;但是Spring捕获异常后不会处理异常,会继续向上抛出,开启多个事务时,也需要try-catch 的使用,避免异常上抛,导致其他事务回滚,逻辑执行异常。

//  所有异常都会回滚,事务:Propagation. REQUIRED
@Transactional(rollbackFor = Exception.class)
public void addUser(){
	......
}

// 所有异常都会回滚,事务:Propagation. REQUIRES_NEW
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
public void addOrder(){
   ......
}

隔离级别:isolation

  1. 推荐一下自己的博客Mysql事务隔离机制: https://blog.csdn.net/zhangyong01245/article/details/93888868
  2. 其实Spring的隔离级别,就是对应数据库隔离级别的一种实现
  3. Spring的事务隔离级别,共有5中:
参数值 名称 解释
Isolation. DEFAULT Default 默认的事务隔离级别,默认是用数据库的事务隔离级别
Isolation. READ_UNCOMMITTED 未提交读 脏读,不可重复读、幻读都存在
Isolation. READ_COMMITTED 已提交读 避免脏读,但是存在不可重复读,幻读
Isolation. REPEATABLE_READ 可重复读 避免脏读和不可重复读,但是有幻读的可能
Isolation. SERIALIZABLE 串行话 避免以上所有读的问题
  1. 示例
 // 所有异常都会回滚,事务隔离机制已提交读
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)

猜你喜欢

转载自blog.csdn.net/zhangyong01245/article/details/95207762