Spring 事务隔离级别和传播行为

本文详细介绍了Spring事务的隔离级别,包括名词的含义、不同隔离级别的概念,以及事务的传播行为,特别是嵌套事务的工作原理。在Spring中,事务管理可以通过注解或编程方式实现,并指出了在特定情况下,如同一个类内部的方法调用,事务配置可能无效的注意事项。
摘要由CSDN通过智能技术生成

事务的隔离级别

名词的含义

名词含义原因
脏读一个事务读取了另一个事务还没有提交的数据一个事务对某数据进行更新,但并未提交,另一事务读取到了该数据,但是前一个事务如果回滚,那么后一个事务就读取到了错误数据
不可重复读一个事务多次读取同一个数据,结果不同一个事务在2次读取某数据之间时,另一个事务对数据进行了更新,导致前一个事务前后读取数据不一致
幻读一个事务多次查询符合某一条件的数据,结果不同一个事务在2次查询某一条件的数据之间时,另一个事务插入了一条符合该条件的数据,导致前一个事务前后查询数据不一致

隔离级别

隔离级别含义描述
SERIALIZABLE串行化事务串行执行,消耗最大
REPEATABLE READ可重复读避免不可重复读,但是会出现幻读
READ_COMMITTED读已提交避免脏读,但是会出现不可重复读和幻读
READ_UNCOMMITTED读未提交会出现脏读,不可重复读和幻读
DEFAULT默认使用数据库默认的事务隔离级别

事务的传播行为

传播行为描述
PROPAGATION_REQUIRED如果上下文已存在事务, 就加入该事务; 否则新建事务
PROPAGATION_SUPPORTS如果上下文已存在事务, 就加入该事务; 否则以非事务方式执行
PROPAGATION_NOT_SUPPORTED如果上下文已存在事务, 就挂起该事务, 以非事务方式执行完, 再恢复上下文事务; 否则直接以非事务方式执行
PROPAGATION_MANDATORY如果上下文已存在事务, 就加入该事务; 否则抛异常
PROPAGATION_NEVER如果上下文已存在事务; 就抛异常; 否则以非事务方式执行
PROPAGATION_REQUIRES_NEW如果上下文已存在事务, 就将上下文事务挂起,然后新建事务,直到新事务执行完,再恢复上下文事务; 否则新建事务
PROPAGATION_NESTED如果上下文已存在事务,就嵌套事务; 否则新建事务

嵌套事务

嵌套事务是子事务套在父事务中执行, 子事务是父事务的一部分. 在进入子事务之前, 父事务会建立一个回滚点.

如果子事务回滚, 父事务会回滚到进入子事务之前建立的回滚点

如果父事务回滚, 子事务也会跟着回滚. 因为父事务结束之前, 子事务不会提交.

提交事务时, 子事务先提交,然后父事务在提交

事务的使用

  1. Spring 注入PlatformTransactionManager的某一个具体实现类JtaTransactionManagerDataSourceTransactionManager
  2. 使用@Transactional标注在某一方法上
  3. 或者使用TransactionTemplate 来进行细粒度化的操作
  4. Spring 中事务默认回滚RuntimeExceptionError的异常
    TransactionAspectSupport#invokeWithinTransaction() ->
    TransactionAspectSupport#completeTransactionAfterThrowing() ->
    DefaultTransactionAttribute#rollbackOn()

注意

在 Spring 中, 同一个类中的方法, 一个方法直接调用另一个方法, 第二个方法上的@Transactional是无效的
例如 :

@Service
public class MyServiceImpl implements MyService {
    public void test1() {
        test2();
    }

    @Transactional
    public void test2() {
    }
}
@RestController
public class MyController {
    @Autowired
    MyService myService;
    @GetMapping("/test1")
    public Object test1(){
        myService.test1();
        return "ok";
    }
    @GetMapping("/test2")
    public Object test2(){
        myService.test2();
        return "ok";
    }
}

MyController#test1() 中, 通过myService.test1() 间接调用myService#test2(), @Transactional是不生效的
MyController#test2() 中, 直接调用myService#test2(),@Transactional生效
另外传播行为和隔离级别也是一样, 因为它们的前提是@Transactional 生效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值