Spring 事务 @Transactional 注解

上期我们讲解了Spring事务的两种实现,其中声明式注解使用了 @Transactional 注解, 接下来我们学习 该注解的使用细节。

我们主要学习 @Transactional注解当中的三个常见属性:

rollbackFor:异常回滚属性,指定能够出发事务回滚的异常类型,可以指定多个异常类型

Isolation:事务的隔离级别,默认值为:Isolation.DEFAULT

1. rollbackFor

@Transactional 默认只在遇到运行时异常和Error时才会回滚,非运行时异常不回滚,即 error及子类,RuntimeException 及子类 才会回滚:

解上次代码我们添加一个测试方法:

java 复制代码
    @Transactional
    @RequestMapping("/test1")
    public Boolean test1(String userName, String password) throws IOException {
        userService.registry(userName, password);
        if(true) {
            throw new IOException();
        }
        return true;
    }

不会回滚

java 复制代码
    @Transactional
    @RequestMapping("/test1")
    public Boolean test1(String userName, String password) throws RuntimeException {
        userService.registry(userName, password);
        if(true) {
            throw new RuntimeException();
        }
        return true;
    }

会回滚

我们可以通过配置 @Transactional 注解中的 rollbackFor 属性来指定出现何种异常类型时事务进行回滚。

java 复制代码
    @Transactional(rollbackFor = Exception.class)
    @RequestMapping("/test1")
    public Boolean test1(String userName, String password) throws IOException {
        userService.registry(userName, password);
        if(true) {
            throw new IOException();
        }
        return true;
    }

会回滚

2. Spring 事务隔离级别

Spring 中事务隔离级别有5种:

  1. Isolantion.DEFAULT:以连接的数据库的隔离事务级别为主。
  2. Isolation.READ_UNCOMMITTED:读未提交,对应SQL标准中 READ UNCOMMITTED
  3. Isolation.READ_COMMITTED:读以提交,对应SQL标准中 READ COMMITTED
  4. Isolation.REPEATABLE_REWAD:可重复读,对应SQL标准中 REPEATABLE READ
  5. Isolation.SERIALIZABLE:串行化,对应SQL标准中 SERIALIZABLE
java 复制代码
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 中事故隔离级别可以通过 @Transational 中的 isolation 属性进行设置

java 复制代码
    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    @RequestMapping("/test")
    public Boolean test(String userName, String password) throws IOException {
        userService.registry(userName, password);
        if(true) {
            throw new IOException();
        }
        return true;
    }

3. Spring 事务传播机制

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

例:

现有两个方法 A 和 B 都被 @Transactional 修饰, A方法中调用了B方法,A方法运行时会开启一个事务,当 A 调用 B 时,B 方法本身也有事务,此时B方法是加入 A 的事务还是创建一个新的事务,就涉及到了事务的传播机制。

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

Spring 事务传播机制有以下7种:

  1. Propagation.REQUIRED:默认的事务传播级别,如果当前存在事务,则加入该事务,否则创建一个新的事务。
  2. Propagation.SUPPORTS:如果当前存在事务,则加入该事务,如果没有事务则以非事务方式运行。
  3. Propagation.MANDATORY:强制性,如果当前存在事务,则加入该事务,如果没有事务就抛出异常。
  4. Propagation.REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起(不使用),创建一个新的事务,该事务与外部事务相互独立。(两个事务的回滚不会互相影响)
  5. Propagation.NOT_SUPPORTED:以非事务方式运行,如果当前存在事务则把当前事务挂起不使用。
  6. Propagation.NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
  7. Propagation.NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行,如果当前没有事务,则创建一个新事务。

这里我们解释以下 Propagation.NESTED , 在嵌套事务的情况下,无论哪个方法发生异常都会导致所有的事务回滚,不过与Propagation.REQUIRED的区别在于,如果 子事务发生异常,可以使用try catch 语句,在catch中把子事务单独进行回滚,而不影响其他事务(因为异常被捕获了,其他事务感知不到),但是如果父事务进行了回滚,则子事务也一定都会回滚。

相关推荐
微三云、小叶4 分钟前
排队免单系统底层设计:四种分配算法拆解,无预支资金的合规营销架构方案
java·前端·软件开发·商业模式·本地生活·商业思维
就叫_这个吧7 分钟前
Java+MySQL+Mybatis+Junit4实现学生信息管理系统
java·mysql·mybatis
乐之者v7 分钟前
xxl-job添加执行器
java
可乐ea32 分钟前
【知识获取与分享社区项目 | 项目日记第 19 天】基于 Elasticsearch 实现关键词检索与业务权重排序
java·大数据·spring boot·mysql·elasticsearch·搜索引擎·全文检索
用户398346161201 小时前
Go-Spring 实战第 18 课 —— App 使用:启动、配置与运行期扩展
spring·go
zzz_23681 小时前
【Spring】面试突击系列(一):IoC 与 DI 深度解析
java·spring·面试
于先生吖1 小时前
前后端分离体育服务项目,场馆计费+线下赛事排行小程序部署开发教程
java·小程序·uni-app
RemainderTime1 小时前
Spring Boot脚手架集成 Spring Security实现生产级RBAC鉴权
spring boot·后端·spring
闪电悠米1 小时前
黑马点评-秒杀优化-01_async_seckill_idea
java·数据库·ide·redis·分布式·缓存·intellij-idea
摇滚侠2 小时前
IDEA 创建 Java 项目 lib 和 resources
java·ide·intellij-idea