查看原文
其他

我来出个题:这些事务会不会回滚?大概率你会错!

翟永超 程序猿DD 2021-11-13

下面这个问题源于前几日在Spring技术交流群里,一个群友提出的关于事务回滚的疑问。

在讨论过程中,我尝试去复现的问题场景,结果发现了另外一个可能让大家会迷惑的情况。

当时在群里说了结果和原因,但微信群范围有限,所以单独写篇文章,拿出来给大家看看,顺便考考大家,对这块是否了解。

问题描述

这个问题的基础工程我用了之前Spring Boot 2.x基础教程中《使用Spring Data JPA访问MySQL》(https://blog.didispace.com/spring-boot-learning-21-3-4/)的案例。

你可以通过下面仓库中的chapter3-4目录获取基础工程:

  • Github:https://github.com/dyc87112/SpringBoot-Learning/
  • Gitee:https://gitee.com/didispace/SpringBoot-Learning/

在这个工程中,定义一个名为User的实体:

@Entity
@Data
@NoArgsConstructor
public class User {

    @Id
    @GeneratedValue
    private Long id;

    @Size(max = 5)
    private String name;
    @Max(50)
    private Integer age;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

}

这里name设置了长度为5,这样可以通过insert语句中的name超长,让其抛出异常,从而可以测试事务的触发。

另外工程中还包含了Spring Data Jpa的数据访问对象UserRepository,用来实现对User实体的数据操作,这里就不放具体代码了。

问题来了

这里数据库采用MySQL 5.7,存储引擎为InnoDB,使用默认事务级别。

下面来调整下这四个问题吧:

问题一:test1会不会回滚?

@Transactional
public void test1() {
    userRepository.save(new User("AAA"10));
    throw new RuntimeException();
}

问题二:test2会不会回滚?

@Transactional
public void test2() {
    userRepository.save(new User("AAA"10));
    try {
        throw new RuntimeException();
    } catch (Exception e) {
        log.error("异常捕获:", e);
    }
}

问题三:test3会不会回滚?(第二句插入name超长)

@Transactional
public void test3() {
    userRepository.save(new User("AAA"10));
    userRepository.save(new User("1234567890"20));
}

问题四:test4会不会回滚?(第二句插入name超长)

@Transactional
public void test4() {
    userRepository.save(new User("AAA"10));
    try {
        userRepository.save(new User("1234567890"20));
    } catch (Exception e) {
        log.error("异常捕获:", e);
    }
}

做个投票,选择你认为的答案(多选):

点击卡片关注我,回复“事务回滚

获取答案,看看你的判断都对吗?

留言说说你错了哪题?看看大家是不是都一样 

如果你觉得这个题可以,转发到朋友圈,考考你身边的人吧

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存