面试官:说说Spring中的事务传播行为

294 阅读2分钟

图片

做一个单纯的程序汪,分享干货,聊聊人生。

微信公众号:后端架构进阶

关注我发现更多的干货,微服务、Spring源码、JVM、SpringCloud Alibaba、K8S等。

如果你觉得本文对你有帮助,麻烦给我点个赞,感谢支持!

历史文章汇总:包含Netty、源码、并发、JVM等

面试官:在开发中,为了保证数据的一致性,我们都会使用事务。那么什么是事务的传播行为呢? 我:额,就是.....

于是决定好好把这个知识点好好梳理下,下次遇到的时候就不会摸不着头脑了。

一、 七种事务传播行为

1、Propagation.REQUIRED

如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。

2、Propagation.SUPPORTS

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

3、Propagation.MANDATORY

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

4、Propagation.REQUIRES_NEW

重新创建一个新的事务,如果当前存在事务,延缓当前的事务。

5、Propagation.NOT_SUPPORTED

以非事务的方式运行,如果当前存在事务,暂停当前的事务。

6、Propagation.NEVER

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

7、Propagation.NESTED

如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务。

奉上七种事务的传播行为。我们默认的传播行为是第一个REQUIRED,那么对应到我们的业务中,具体是什么样的表现呢?我们来演示拆解。

二、准备工作

我们准备一个SpringBoot项目,具体就不在这详细阐述了。数据库建立了简单的user表,我使用的是mybatis-plus作为数据库操作的工具,省去很多繁杂的操作。我也非常推荐大家可以用这种方式。

图片

然后就是搭建一个简答的SpringBoot项目,我的目录结构如下所示。主要演示的是一个事务里面调用另外一个事务。验证我们的传播行为。

图片

然后UserService2里面循环调用UserService里面的方法。如果是最后一条我们就抛异常。

@Service
public class UserService2 {

    @Resource
    private UserService userService;

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertBatch() {
        for (int i = 0; i < 5; i++) {

            if (i == 4) {
                throw new RuntimeException();
            }
            userService.save();
        }
    }
}

UserService里面调用insert方法,进行数据的插入。

@Transactional(propagation = Propagation.REQUIRED)
public int save() {
    long l = IdUtil.getSnowflake().nextId();
    User u = new User();
    u.setTid(l);
    u.setUsername(l + "");
    u.setPassword("" + l);
    int insert = userMapper.insert(u);
    return insert;
}

ok,接着我们开始演示。

三、事务传播行为

事务传播行为默认为REQUIRED, 一般我们也不会去修改。方法上加了事务,如果不指明传播行为,默认就是REQUIRED

我的Controller里面写了个方法,直接调用api来请求我们这个方法。

@GetMapping("save")
    public String save() {
        userService2.insertBatch();
        return "操作执行成功...";
    }

可以看到我们的控制台报错,是我们手动抛的,这里需要注意的点是,如果我们把这个错误cach了,那么数据还是回滚不了的。切记。

图片

数据库数据也没存进去,就是正常的了。

图片

到这里,我们再回想一下我们的默认传播行为是:如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。 可见,在同一个事务里面执行了请求,失败后统一回滚了。

我们再来随便演示一个,比如:NEVER控制台还是报错,不过数据库插入了四条数据,第五条因为报错没插入进去。没事务,所以没回滚,符合我们的预期。

图片

四、总结

其他的就不一一演示了,大同小异,主要就是把面试遇到的一个问题给做个总结和梳理。后面就不会像现在一样不知道如果去答复了。 很多东西只有自己亲手去尝试,去挖掘才会有更清晰的认识。后面也会把自己在面试中遇到的问题做个梳理。

总结

以上就是今日的内容总结和分享,感谢各位大佬的 点赞关注收藏

微信公众号:后端架构进阶

更多文章正在赶来,喜欢记得给我点个 👍 ,感谢支持!

公众号文章同步更新!关注我,不迷路!