写点什么

Spring 事务,你真的用对了吗 (下篇)?

用户头像
废材姑娘
关注
发布于: 2021 年 01 月 06 日
Spring 事务,你真的用对了吗(下篇)?

在上一篇关于事务的文章中,我们遗留了一个问题,@Transactional 注解中的参数 Propagation = Propagation.REQUIRED 是什么?今天我们就来揭开谜底。

这个东西可厉害了, 他是 Spring 为我们提供的事务传播机制,帮我们完成各种业务需求。比如依旧是两个 service 方法。我们想让外部的方法异常回滚,内部方法的操作不回滚, 上一篇中提到的方法就无法满足了。别急,学完了今天的内容, 你就能运用自如了, 各种事务问题也都难不倒你了。

首先,让我们来看一下 Spring 都为我们提供了哪几种事务的传播机制,他们的作用都是什么, 我简单罗列如下: 


那每一个传播机制都有什么样的特点呢, 我们依旧通过代码实验来学习。 

Propagation.REQUIRED(默认)

外部事务和内部事务是一个事务, 所有是一荣俱荣,一损俱损, 即内部回滚会导致外部回滚, 外部回滚也会导致内部回滚, 不滚外部是否 catch 住了内部方法的异常。

未 catch 内部方法异常



结果: 两条记录都没有插入成功

catch 内部方法的异常



结果: 两条记录都没有插入成功

外部方法抛出异常



结果: 两条记录都没有插入成功

Propagation.REQUIRED_NEW

外部和内部不是同一个事务,内部事务和外部事务是相互独立的, 可以互相不影响。前提是不能让外部事务感知到异常。

未 catch 住内部方法异常



结果: 两条记录都没有插入成功

catch 住内部方法异常


外部方法抛出异常


结果: 外部方法记录插入失败, 内部方法第一条记录成功

Propagation.NESTED

内部事务是外围事务的子事务,如果外部事务回滚,子事务一定回滚,但子事务可以单独回滚, 而不影响外部事务,前提是不能让外部事务感知到异常。

未 catch 住内部方法异常



结果: 两条记录都没有插入成功

catch 住内部方法异常



结果: 第一条记录成功插入, 第二条记录失败

外部方法抛出异常



结果: 两条记录都没有插入成功


前面讲解的都是我们平时开发时会用到的, 还有一种是 Propagation.NOT_SUPPORTED,这种是以非事务的方式运行, 所以不管内部还是外部方法抛出异常, 都不会回滚方法本身。其余几种少用到, 大家就自己动手做做实验学习一下吧。

总结


综合上一篇的内容, 我们可以看出 Spring 事务真的可以解决我们业务需求的大部分场景。在我们需要事务时,直接使用 @Transactional 注解就好。当我们的事务跨了多个 service 时,就要考虑我们期望它们的行为是什么,是同一个事务,还是各自独立的事务,是内部不使用事务,还是外部不使用事务。分析完需求再选择合适的事务传播机制就好啦。





发布于: 2021 年 01 月 06 日阅读数: 39
用户头像

废材姑娘

关注

废材姑娘 2018.01.24 加入

大家叫我双儿,梦想着成为韦小宝的老婆 欢迎关注我的个人公众号----废材姑娘,回复“双儿”加我微信,让我们一起探索多彩的世界。

评论

发布
暂无评论
Spring 事务,你真的用对了吗(下篇)?