文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

面试官:@Transactional 与 @Async 可以同时使用吗

2024-11-29 20:07

关注

一、@Transactional 与 @Async  可以同时使用吗

首先我们还是先写个 demo 看看运行结果。

demo 地址:https://github.com/zuiyu-main/EncryptDemo/tree/mysql-transactional-async

代码如下,使用注入的方式调用 TestService#test 方法。TestService#test 方法上同时使用 @Async 与 @Transactional 注解标注。

注意:需要在启动类中加入@EnableAsync注解,不了解的可以看下上一篇 @Async 原理

让我们先看下运行结果。

通过上图可以知道,方法已经在异步线程中执行,方法的异常也已经抛出,数据库中也没有插入对应的数据。得出结论,@Transactional   可以与 @Async 注解同时使用,且事务可以生效。

这里提前透漏一个知识点把,大家可以把断点打在TransactionAspectSupport#invokeWithinTransaction()方法中243行位置处,判断代码是走245行的回滚逻辑还是258行的提交逻辑。

在或者在PlatformTransactionManager接口的 commit 或者 rollback 打上断点,看执行哪个方法。

二、@Transactional 注解原理

上一篇文章中说过了 @Async 注解的原理,还没看过的小伙伴可以过去看一眼哦。@Transactional 注解的工作原理也类似,都是 AOP 实现。

在哪找入口呢,@Async 注解的学习过程中,我们是从注解入手的,@Transactional 同样也可以,如下图所示。

所以上文中提到验证事务是否生效的方式中我就是从这受启发的。

不过今天我们看另一种方式,就是通过断点查看调用栈的方式。

这种方式有个缺点,就是假如事务是没有生效的,也就是说没有被 spring 代理,此时是无法达到我们的预期的。

所以有的时候看事务有没有生效,也可以通过这个方式。

首先在我们的异步方法第一行打入断点。

通过这一个断点,我们就可以知道两个消息。

进入到方法内部,需要注意的是 tas.getTransactionAttribute()。如果这个 transaction attribute 是空,说明这个方法是没有被事务管理的。

在  tas.getTransactionAttribute() 中,执行的是 AbstractFallbackTransactionAttributeSource 下的 getTransactionAttribute 方法,而在 getTransactionAttribute 方法中有一行 computeTransactionAttribute 方法,在该方法中有如下这样一行代码,这也是事务失效场景之一的 priviate 方法不支持事务。

事务失效场景:private 方法不支持事务。

如果你在 debug 时没有拦住该方法,需要重启,在程序启动时会缓存该方法的事务属性。

我们继续回到 TransactionAspectSupport#invokeWithinTransaction 方法,继续往下走。

在回滚事务的方法中,进行了判断,这就是另一种事务失效的场景,异常不匹配。所以在使用事务注解时一定要注意。

事务失效场景:异常类型不匹配。

当我们没有指定异常类型时,默认只对 RuntimeException 和 Error 有效。

所以,我们总结一下,与 一文搞懂@Async 原理一起阅读更佳。

现在我们知道了 @Transactional 与 @Async 注解的原理,那么当他们两个互不相干的方法互相调用还会生效吗?

只验证注入方式调用的形式。

三、@Transactional 调用 @Async

结论:test方法中事务生效,异步方法 test2 事务不生效。

异步方法  test2 上也加入事务注解

结论:test方法与 test2方法两个独立的事务,互不相关。

四、@Async 调用 @Transactional

结论:test 方法会因为 test2 方法执行报错而异常终止,test2 方法事务回滚。

如果我们把 test 方法中插入数据的代码移动到调用 test2 方法之前。

结论:test 方法中数据插入成功,test2 数据插入失败,事务回滚。

总结

我们在上一篇文章中学习了 @Async 注解的原理,今天看了 @Transactional 注解的原理。

通过写代码的形式,验证了:

来源:醉鱼Java内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯