首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【SpringBoot】@Transactional 详解 && 事务隔离级别 && 事务传播机制

【SpringBoot】@Transactional 详解 && 事务隔离级别 && 事务传播机制

原创
作者头像
lirendada
发布2026-08-21 14:44:56
发布2026-08-21 14:44:56
490
举报
文章被收录于专栏:JavaJava

@Transactional 详解

这里主要介绍注解中三个常见属性:

  1. rollbackFor:异常回滚属性。指定能够触发事务回滚的异常类型。可以指定多个异常类型
  2. Isolation:事务的隔离级别。默认值为 Isolation.DEFAULT
  3. Propagation:事务的传播机制。默认值为 Propagation.REQUIRED

一、异常回滚属性 rollbackFor

@Transactional 默认只在遇到 RuntimeExceptionError 时才会回滚,而非运行时异常不回滚

如果我们需要所有异常都回滚,需要来配置 @Transactional 注解当中的 rollbackFor 属性,通过这个属性指定出现何种异常类型时事务进行回滚

代码语言:javascript
复制
// Controller 层
@RequestMapping("/r2")
public String r2(String name, String password) throws IOException {
    userService.registryUserWithTx(name, password);
    return "r2";
}

// Service 层
@Transactional(rollbackFor = Exception.class)
public void registryUserWithTx(String name, String password) throws IOException {
    userRepository.save(new User(name, password));
    log.info("用户数据插入成功");
    
    if (true) {
        throw new IOException(); // 模拟异常
    }
}

发现虽然程序抛出了异常,但是事务依然进行了回滚!

二、Spring事务隔离级别 Isolation

隔离级别

含义

Isolation.DEFAULT

以连接的数据库的事务隔离级别为主

Isolation.READ_UNCOMMITTED

读未提交

Isolation.READ_COMMITTED

读已提交

Isolation.REPEATABLE_READ

可重复读

Isolation.SERIALIZABLE

串行化

它的实现如下所示:

代码语言:javascript
复制
public enum Isolation {
    DEFAULT(-1),
    READ_UNCOMMITTED(1),
    READ_COMMITTED(2),
    REPEATABLE_READ(4),
    SERIALIZABLE(8);
    
    private final int value;
    
    private Isolation(int value) {
        this.value = value;
    }
    
    public int value() {
        return this.value;
    }
}

Spring 中事务隔离级别可以通过 @Transactional 中的 isolation 属性进行设置:

代码语言:javascript
复制
@Transactional(isolation = Isolation.READ_COMMITTED)
@RequestMapping("/r3")
public String r3(String name,String password) throws IOException {
    //... 代码省略
    return "r3";
}

三、Spring事务传播机制 Propagation

1. 什么是事务传播机制

事务传播机制就是: 多个事务方法存在调用关系时,事务是如何在这些方法间进行传播的

比如有两个方法 AB 都被 @Transactional 修饰,A 方法调用 B 方法

A 方法运行时,会开启一个事务。当 A 调用 B 时,B 方法本身也有事务,此时 B 方法运行时,是加入 A 的事务呢,还是创建一个新的事务呢?

这就涉及到了事务的传播机制。

  • 事务隔离级别 解决的是 多个事务同时调用一个数据库的问题
  • 事务传播机制 解决的是 一个事务在多个方法之间传递的问题

2. 事务的传播机制有哪些

@Transactional 注解支持事务传播机制的设置,通过 propagation 属性来指定传播行为。

传播机制

作用

Propagation.REQUIRED

默认的事务传播级别。如果当前存在事务,则加入该事务。如果当前没有事务,则创建一个新的事务。

Propagation.SUPPORTS

如果当前存在事务,则加入该事务。如果当前没有事务,则以非事务的方式继续运行。

Propagation.MANDATORY

如果当前存在事务,则加入该事务。如果当前没有事务,则抛出异常。

Propagation.REQUIRES_NEW

如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部方法都会新开启自己的事务,且开启的事务相互独立,互不干扰。

Propagation.NOT_SUPPORTED

以非事务方式运行,如果当前存在事务,则把当前事务挂起,不使用它。

Propagation.NEVER

以非事务方式运行,如果当前存在事务,则抛出异常。

Propagation.NESTED

如果当前存在事务,则创建一个事务作为当前事务的子事务来运行。如果当前没有事务,则创建一个新的事务。

实现类如下所示:

代码语言:javascript
复制
public enum Propagation {
    REQUIRED(0),
    SUPPORTS(1),
    MANDATORY(2),
    REQUIRES_NEW(3),
    NOT_SUPPORTED(4),
    NEVER(5),
    NESTED(6);
    
    private final int value;
    
    private Propagation(int value) {
        this.value = value;
    }
    
    public int value() {
        return this.value;
    }
}

💥nestedrequired 的区别

  • 整个事务如果全部执行成功,二者的结果是一样的。
  • 如果事务部分执行成功
    • REQUIRED 加入事务会导致整个事务全部回滚
    • NESTED 嵌套事务可以实现局部回滚,不会影响上一个方法中执行的结果。

      嵌套事务之所以能够实现部分事务的回滚,是因为事务中有一个保存点(savepoint)的概念,嵌套事务进入之后相当于新建了一个保存点,而滚回时只回滚到当前保存点。 REQUIRED 是加入到当前事务中,并没有创建事务的保存点,因此出现了回滚就是整个事务回滚,这就是嵌套事务和加入事务的区别!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • @Transactional 详解
    • 一、异常回滚属性 rollbackFor
    • 二、Spring事务隔离级别 Isolation
    • 三、Spring事务传播机制 Propagation
      • 1. 什么是事务传播机制
      • 2. 事务的传播机制有哪些
      • 💥nested 和 required 的区别
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档