你知道@Transactional注解的失效场景吗?

聊一聊Spring中@Transactional注解及其失效的七种场景 文章目录一、事务(基于AOP)二、@Transactional介绍三、@Transactional失效场景 说明:当我准备写我知道的那几个场景时,我发现有人比我写的更好,关键是好得多,于是我就用了这位博主的文章,由于不是一个平台我就直接将有些内容复制加以修改,感谢这位博主!他地址:https://www.cnblogs.com/frankyou/p/12691463.html 一、事务(基于AOP) 事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两 阅读详情

在使用Spring的时候,进行事务管理变得相当简单:只要在方法上加上@Transactional就可以了,Spring就帮我们做了事务的开启、提交和回滚等操作,甚至我一度认为@Transactional就是等于Spring事务,只要是见到有数据库操作的方法,默认的统统加上此注解,自以为是的就万事大吉了。你是不是也有与我相同的经历呢:)

其实,@Transactional也不是在任何的场景下都有效的,有时候会莫名的失效,在介绍之前呢,我们先来认识一下。

1、@Transactional注解可以用在哪些地方呢?

作用于类:表示所有public方法都配置相同的事务信息。

作用于方法:代表方法的事务信息,其会覆盖类的事务哦!

作用于接口:这种方法极力不推荐,因为一旦使用cglib,注解会失效。

例如以下示例:

@Service
@Slf4j
public class UserHelper extends ServiceImpl<UserMapper, UserDO> {

    @Transactional(rollbackFor = Exception.class)
    public Long createNewUser(RegisterRequest request) {
        UserDO userDO = new UserDO();
        userDO.setLoginName(request.getLoginName());
        userDO.setLoginPwd(request.getLoginPwd());
        userDO.setCreateTime(new Date());
        userDO.setUpdateTime(new Date());
        this.save(userDO);
        //这里还可以保存userinfo扩展信息,双表操作,需要事务
        return userDO.getId();
    }
}

2、@Transactional注解还有哪些属性呢?

属性

描述

备注

propagation

事务的传播行为,默认值为 Propagation.REQUIRED:如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。

还有Propagation.SUPPORTS、Propagation.MANDATORY等

isolation

事务的隔离级别,默认值为 Isolation.DEFAULT,代表使用数据库默认的隔离级别

还有
Isolation.READ_UNCOMMITTED、Isolation.READ_COMMITTED等

timeout

事务的超时时间,默认-1

如果超过时间事务还没有执行完毕,则自动回滚事务

readOnly

只读事务,默认值为false

rollbackFor

用于指定触发事务回滚的异常类型

如上例,Spring默认是运行时异常才会回滚

noRollbackFor

用于指定不触发事务回滚的异常类型

接下来,我们一起看看@Transactional失效的场景。

1、作用在非public方法上会失效

原因是在使用Spring AOP 代理时,会间接调用
AbstractFallbackTransactionAttributeSource的方法computeTransactionAttribute获取事务信息,如果是非public就直接返回了,如下源码:

 @Nullable
    protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
        if (this.allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
            return null;
        } else {
            Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
            TransactionAttribute txAttr = this.findTransactionAttribute(specificMethod);
            if (txAttr != null) {
                return txAttr;
            } else {
                txAttr = this.findTransactionAttribute(specificMethod.getDeclaringClass());
                if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
                    return txAttr;
                } else {
                    if (specificMethod != method) {
                        txAttr = this.findTransactionAttribute(method);
                        if (txAttr != null) {
                            return txAttr;
                        }

                        txAttr = this.findTransactionAttribute(method.getDeclaringClass());
                        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
                            return txAttr;
                        }
                    }

                    return null;
                }
            }
        }
    }

2、propagation属性配置错误


TransactionDefinition.PROPAGATION_SUPPORTS:有没有事务无所谓


TransactionDefinition.PROPAGATION_NOT_SUPPORTED:非事务方式执行


TransactionDefinition.PROPAGATION_NEVER:有事务抛异常

3、rollbackFor设置错误

Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。若需要在特定异常下回滚,则需要指定,比如第一个示例。

4、在同一个类中,方法调用

这个尤其被大家不熟悉,红色标出。

@Transactional(rollbackFor = Exception.class)
    public Long createNewUser(RegisterRequest request) {
        UserDO userDO = new UserDO();
        userDO.setLoginName(request.getLoginName());
        userDO.setLoginPwd(request.getLoginPwd());
        userDO.setCreateTime(new Date());
        userDO.setUpdateTime(new Date());
        this.save(userDO);
        //这里还可以保存userinfo扩展信息,双表操作,需要事务
        addUserInfo();
        return userDO.getId();
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void addUserInfo() {
        //.....
    }

原因是什么,大家可以想一想,我们下一章来分析:)

5、异常被catch给吃掉了

@Transactional(rollbackFor = Exception.class)
    public Long createNewUser(RegisterRequest request) {
        try {
            UserDO userDO = new UserDO();
            userDO.setLoginName(request.getLoginName());
            userDO.setLoginPwd(request.getLoginPwd());
            userDO.setCreateTime(new Date());
            userDO.setUpdateTime(new Date());
            this.save(userDO);
            return userDO.getId();
        } catch (Exception e) {
            log.error("异常了",e);
        }
        return null;
    }

6、数据库底层不支持事务,比如mysql的myisam引擎。

笔者只想到这几个场景,不知道还有没有其它的呢,大家可以在评论区留言!

Spring——@Transactional事务注解原理及失效场景 Spring中的事务注解你真的用对了吗?其中的原理、传播机制、失效场景你都理解了吗 阅读详情

相关推荐

@Transactional 注解使用场景详细说明包括(不生效的场景,事务回滚)

@Transactional 注解使用场景详细说明包括(不生效的场景,事务回滚)

daralisdan的博客 1372

@Transactional详解(作用、失效场景与解决方法)

@Transactional非常的好用,只需要一个注解就可以不用管事务操作了,只需要注重自己的业务代码就可以了 @Transactional也有缺点,比如你要注意上诉的几种失效情况,他有个局限性,他的最小粒度要作用在方法上,也就是说,如果想要给一部分代码块增加事务的话,那就需要把这个部分代码块单独独立出来作为一个方法。而且AOP要生成一个动态代理类,所以会慢一点 但是谁会管这些啊,好用就行了,也不是不能忍的问题,这跟他的好处根本不成正比,当然如果要使用编程式事务也可以,看个人爱好,反之小编一直在用

我认不到你的博客 3万+

如何在STM32上5分钟搞定nanopb协议传输?附完整代码示例

本文提供了在STM32微控制器上快速集成nanopb协议传输的实战指南。通过详细的步骤,从.proto文件定义、代码生成到STM32CubeIDE项目移植,帮助开发者利用nanopb这一轻量级Protocol Buffers C语言实现,在5分钟内构建高效、跨平台的嵌入式设备通信框架,并附有完整的代码示例。

jwt8token的博客 839

@Transactional注解超详细

Transactional注解是Spring框架中用于声明式事务管理的关键注解。本文将深入探讨@Transactional注解的作用、使用方式和常见属性,并结合代码实例演示其在实际项目中的应用,以帮助读者更好地理解和使用该注解。@Transactional注解是Spring框架中用于声明式事务管理的关键注解。通过使用@Transactional注解,我们可以更加方便地管理事务,保障数据的一致性和可靠性。在实际项目中,合理使用@Transactional注解可以提高「开发效率 」和代码「可维护性 」。

Wzill 3万+

用Docker部署ERPNext V15:从架构原理到生产落地的完整指南

容器化部署正在重塑企业级应用的分发与运维方式,ERPNext作为开源ERP中的佼佼者,其基于Frappe框架的模块化设计天然适合用Docker进行编排。理解容器、镜像与编排的关系,是掌握ERP系统部署的基础。Frappe框架负责数据模型与API,ERPNext则承载销售、采购、财务等业务逻辑,两者通过Docker容器解耦为可独立扩展的组件。这种架构带来的价值在于:环境一致性、快速迁移与弹性伸缩,使中小团队也能以较低成本自托管业务系统。无论是替代传统SaaS,还是构建内部管理平台,掌握容器化部署已成为运维与开

weixin_32325225的博客 139

建行报专版报道建设银行金融科技发展历程

经过十多年的建设,总行前中后台部门都有了自己的业务系统,但系统“部门”特征显著,渠道、客户、产品的横向整合不足,产品系统层次化、结构化、参数化程度不高,渠道支持产品快速部署以及跨渠道服务能力不足,管理分析类系统建设相对滞后,系统较弱的可扩展能力在应对高速增长的交易量时已疲态尽显,同时安全稳定运行的压力和风险日益积聚。站在新的历史起点上,科技条线将聚焦主责主业,完善信息科技管理体系,紧紧围绕安全生产中心任务,持续推动技术能力复用共享和自主可控,为全行做好金融五篇大文章,推动业务高质量发展提供技术支撑。

银行信息系统应用架构详解 387

@Transactional 注解

@Transactional 注解相信大家并不陌生,平时开发中很常用的一个注解,它能保证方法内多个数据库操作要么同时成功、要么同时失败。使用@Transactional注解时需要注意许多的细节,不然你会发现@Transactional总是莫名其妙的就失效了。 一、事务 事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两种。 1、编程式事务 是指在代码中手动的管理事务的提交、回滚等操作,代码侵入性比较强。 编程式事务方式需要开发者在代码中手动的管理事务

csdnlaiyanqi的博客 5万+

(王道计算机组成原理笔记)第一章计算机系统概述-第二节:计算机系统层次结构 1(计算机系统组成、计算机硬件)

文章目录一:冯诺依曼体系结构(1)存储程序计算机(2)层次结构二:计算机硬件概述(1)存储器A:存储元、存储单元、存储体、存储字和存储字长B:MAR 一:冯诺依曼体系结构 在冯诺依曼体系结构中,计算机的硬件主要有**存储器,运算器,控制器,输入和输出设备(也叫做I/O设备)**组成。 (1)存储程序计算机 冯诺依曼体系结构也叫做存储程序计算机,计算器和计算机的唯一区别就是计算器是不能编程的,只能做电路板中设定好的固定的运算。 这也就意味着计算器本质就是一个不能编程的计算机,其在硬件层面已经将逻辑写死,如果

快乐江湖的博客 1万+

SpringBoot @Transactional(rollbackFor = Exception.class)回滚失效分析

1.场景介绍 1.SpringBoot中业务层方法中使用了try catch 导致@Transactional(rollbackFor = Exception.class)注解失效 2.操作演示 1.首先我们根据当前代码进行运行查看出现异常的时候时候会进行回滚 此时我们可以看到代码运行47行(第二个修改)时出现了异常,而我们已经添加了 @Transactional(rollbackFor = Exception.class)注解 正常清空下会发生回滚也就是数据库值不变 但此时我们来观察数据库会发现

xiaoq的博客 4160

实测!Gemini+ChatGPT赋能学术写作:我的论文写作SOP(附提示词)

各位同仁好,我是七哥。一个在高校里从事人工智能相关领域研究,钻研用大模型AI实操的学术人。可以和七哥交流学术写作或Gemini、GPT、Claude等大模型学术实操相关问题,多多交流,相互成就,共同进步。为什么ChatGPT逻辑清晰却写不长?为什么Gemini能深入分析但废话连篇?这其实是两种模型架构的本质差异,GPT系列擅长指令跟随和语言精炼,而Gemini原生支持超长上下文,适合深度文本生成。两者在深度生成与精炼表达上形成了天然互补。我们可以将它们组合起来使用发挥他们各自的特长。

智能AI让学术科研更容易 523

【Python百日进阶-Web开发-Feffery】Day385 -“一起Dash”训练营Lesson-07_利用fac构建表单(上)

文章目录前言:fac是什么?“人生苦短,我用Python;Web开发,首选Feffery!”↓↓↓ 今日笔记 ↓↓↓一、费老师课堂1.1 什么是表单1.2 页面效果1.3 课堂源码二、课后作业2.1 页面效果2.2 项目源码 前言:fac是什么? feffery-antd-components(简称fac),是国内大佬费弗里(Feffery)老师基于著名的React UI组件库ant design进行二次开发,将ant design中的诸多实用组件及特性引入Dash,帮助开发者使用极低的纯Python代

专注于医院数据分析技术与系统开发的创作与分享。 253

【spring】@Transactional 注解失效的原因及解决办法

面试中经常会被问到事务失效的场景有哪些,其实在开发中,若是不了解事务失效的场景,当你觉得加了事务,就会回滚,就大错特错了,今天就来了解一下吧。

来到人间不过是个蹭饭的客人,还挑什么酸甜苦辣。 7493

【雕爷学编程】Arduino动手做(75)---TTL转RS-485模块之二线制可以实现真正的多点双向通信

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来---小小的进步或是搞不掂的问题,希望能够抛砖引玉。 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 实验七十五:TTL转RS-485模块 MAX485 RS485模块 MAX485 是一个8.

雕爷学编程 1万+

spring事务(注解 @Transactional )失效的12种场景

文章目录一 、事务不生效【七种】1.访问权限问题 (只有public方法会生效)2. 方法用final修饰,不会生效3.同一个类中的方法直接内部调用,会导致事务失效3.1 新加一个Service方法3.2 在该Service类中注入自己3.3 通过AopContent类4.(类本身) 未被spring管理5.多线程调用6.(存储引擎)表不支持事务7.未开启事务二、事务不回滚【五种】1.错误的传播特性2.自己吞了异常3.手动抛了别的异常4.自定义了回滚异常5.嵌套事务回滚多了三、大事务与编程式事务1. 大事务

憧憬的专栏 4万+

51、基于深度卷积神经网络的自闭症分类研究

本研究提出了一种基于深度卷积神经网络的自闭症分类方法,通过融合VGGNet-19和ResNet-52模型的特征,并在决策层采用SVM分类器,实现了对自闭症谱系障碍(ASD)和典型发育(TD)个体的准确区分。研究使用ABIDE数据集,结合数据增强和特征拼接技术,取得了88.12%的分类准确率和0.88的ROC曲线下面积。结果表明,该方法在自闭症自动诊断中具有良好的性能,同时研究也探讨了其局限性,并展望了未来改进方向,如多模态数据融合、迁移学习和模型可解释性的提升。

grpc6streamer的博客 132

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

@Transactional 注解的失效场景

作者简介:大家好,我是码炫码哥,前中兴通讯、美团架构师,现任某互联网公司CTO,兼职码炫课堂主讲源码系列专题代表作:《jdk源码&多线程&高并发》,《深入tomcat源码解析》,《深入netty源码解析》,《深入dubbo源码解析》,《深入springboot源码解析》,《深入spring源码解析》,《深入redis源码解析》等联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬。。下面码哥就来介绍常见的失效的场景。

smart_an的专栏 980

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

@Transactional 注解失效的3种原因及解决办法

第一种 l注解标注方法修饰符为非public时,解将会不起作用。例如以下代码。 定义一个错误的@Transactional标注实现,修饰一个默认访问符的方法 在同一个包内,新建调用对象,进行访问。 测试用例 以上的访问方式,导致事务没开启,因此在方法抛出异常时,;操作不会进行回滚。如果方法改为public的话将会正常开启事务,将会进行回滚。在类内部调用调用类内部l标注的方法。这种情况下也会导致事务不开启。示例代码如下。 设置一个内部调用 测试用例。 上面就是使用的测试代码,运行测试知道,外部调用事务方法能够

qq_45228323的博客 1万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

@Transactional 注解的12种失效场景

666

weixin_70280523的博客 1209

@Transactional注解的方法之间调用事务是否生效及其他事务失效场景总结

首先,我们需要知道,Spring是通过代理管理事务的,方法和方法之间的调用分为两种情况: 1.不同类之间的方法调用。如类A的方法a()调用类B的方法b(),这种情况事务是正常起作用的。只要方法a()或b()配置了事务,运行中就会产生代理,开启事务; 2.同一个类的不同方法之间的调用。以同类中方法a()调用方法b()为例: 1).方法a()没有开启事务,此时调用方法b(),无论被调用的b()是否配置了事务,事务都不会生效 2).方法a()开启了事务,如声明式标注了@Transactional注解,此时

qq_42769721的博客 1万+

@Transactional注解学习

接口。

qq_37080455的博客 1031

@Transactional注解失效场景之——同类中方法调用,事务失效

文章目录一、亲身案例二、改进方式三、原理分析 该篇博客为总结自己曾写下的Bug 一、亲身案例 当时的场景为:在controller层获取一笔交易单的信息(前台传给controller层为Map类型的键值对),然后controller层直接将这个Map参数对象转发给Service层,在Service层进行一个对象属性的封装,继而调用mapper层接口完成数据的持久化。 问题出现在Service层,由于这一笔交易单信息会涉及多张表的数据信息,为了代码结构的优美,我特地在Service层的方法中,调用同类

持续Java学习中 3850

【追根究底】 为什么@Transactional注解失效了?

==> 学习汇总(持续更新) ==> 从零搭建后端基础设施系列(一)-- 背景介绍 新手疑问之为什么我已经加上了@Transactional注解,还是失效呢??? 这个很好回答,要么没有生成代理类调用,要么没有开启事务。可以参考细说@Transactional用法及原理 老鸟致命疑问之为什么我已经加上了@Transactional注解,并且事务确认已经开启,最后已经生成...

_ACME_的博客 3076

@Transactional失效问题

一般来说,正向思维是想办法让updateUser()事务起效,但方法1却采用了逆向思维:让selectUser()的事务起效,从而把updateUser()放在一个更大的事务中,最终控制事务。由于test不存在事务,于是selectUser()也就没有事务,而this.updateUser()本身事务失效,所以最终整个调用事务失效。导致事务失效的根本原因在于,非事务方法中调用updateUser()本质上就是this.updateUser(),而this并不是代理对象,而是普通对象(后面再解释)。

smart_an的专栏 1691

@Transactional 失效场景

Spring事务失效是常见问题,主要分为三类:1)自身调用问题,如类内方法调用绕过代理;2)配置错误,包括非public方法、final方法、异常类型不匹配或被捕获;3)环境问题,如MyISAM引擎、多线程调用或传播机制错误。排查顺序建议:检查日志、注解配置、调用方式、方法权限和数据库引擎。关键解决方案包括使用代理对象调用、指定rollbackFor、避免捕获异常等。

Liaka的博客 650

@Transactional 注解失效的 8 大场景,看看你都遇到过几个?

转自:Yang_yangyang 链接:blog.youkuaiyun.com/Yang_yangyang/article/details/114359881用 Spring 的 @Transacti...

程序员闪充宝 247

10 种 Spring 事务失效的常见场景,你知道几个?

10 种 Spring 事务失效的常见场景,你知道几个?

abcafdsgr123456789的博客 1564
上一篇: 为什么内部方法调用会导致@Transactional失效?
下一篇: Redis高频面试题大集合,面试官:记不住建议进厂打螺丝
Javaesandyou
博客等级 码龄5年 742粉丝 563原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值