Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >聊一聊使用Spring事物时不生效的场景

聊一聊使用Spring事物时不生效的场景

作者头像
小四的技术之旅
发布于 2023-09-06 06:44:05
发布于 2023-09-06 06:44:05
22900
代码可运行
举报
运行总次数:0
代码可运行

前言

今天介绍一下Spring事物不生效的场景,事物是我们在项目中经常使用的,如果是Java的话,基本上都使用Spring的事物,不过Spring的事物如果使用不当,那么就会导致事物失效或者不回滚,最终导致数据不一致,所以很有必要去研究一下Spring事物不生效的一些场景,避免掉坑。

下面我们意义列举不生效的场景,并给出解决方法。

一.类没被Spring管理

如果我们的类没有被Spring管理,那么即使使用了Spring事物也不会生效,要让Spring管理我们的类,需要标注@Component,@Service等注解。

二.没有标注@Transactional注解的方法调用了标注@Transactional注解的方法

如果一个方法没有使用@Transactional注解,但是它去调用了带@Transactional注解的方法,那么当前方法的事物不生效。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public void saveUser(User user) throws Exception {
        save(user);
    }

    @Transactional(rollbackFor = Exception.class)
    public void save(User user) {
        try {
            userDao.save(user);
            exceptionMethod();
            roleService.save(user.getRole());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

如上所示,saveUser方法调用了save方法,但是saveUser没有标@Transactional注解,而它调用了save方法,save方法标了@Transactional,不过事物不会生效,这是因为方法没被代理,直接是普通方法调用,所以事物自然不生效。

如果一个方法中调用了其他方法,需要在主方法上加@Transactional注解这个方法才能被代理,如下代码,当然,远程调用@Transactional就不生效了,就需要分布式事物了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Transactional(rollbackFor = Exception.class)
    public void saveAnnotation(User user) throws Exception {
        save(user);
    }

    public void save(User user) {
        try {
            userDao.save(user);
            exceptionMethod();
            roleService.save(user.getRole());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

三.异常使用不正确

如果异常使用不当,那么事物也不会生效,这里的异常有两种,一种是我们抛出的异常,一种是@Transactional注解所接受的异常。

1.如果我们在程序代码中自己捕获了异常导致Spring事物捕获不到异常,那么事物也不会生效,如下,exceptionMethod方法捕获了异常并打印异常信息,那么异常并不会被Spring事物捕获到,所以事物并不会回滚。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Transactional(rollbackFor = Exception.class)
    public void saveAnnotation(User user) throws Exception {
        userDao.save(user);
        exceptionMethod();
        roleService.save(user.getRole());
    }

    private void exceptionMethod() throws Exception {
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

如果需要事物回滚,那么就需要将异常抛到saveAnnotation方法,这样Spring事物才能感知到异常,从而进行事物回滚。

2.@Transactional注解有一个属性rollbackFor,它代表回滚的异常,也就是说只有捕获到这种异常事物才会回滚,它默认的是RunTimeException。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Transactional
    public void saveAnnotation(User user) throws Exception {
        userDao.save(user);
        exceptionMethod();
        roleService.save(user.getRole());
    }

    private void exceptionMethod() throws Exception {
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            throw new Exception("抛出异常");
        }
    }

如上代码,exceptionMethod方法抛出了Exception异常,而@Transactional注解我们没有指定rollbackFor,所以使用的是默认的RunTimeException,所以事物不能回滚,如果我们需要事物回滚,需要让rollbackFor指定的异常是抛出异常的父类或者和自己一样才行,如下所示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Transactional(rollbackFor = Exception.class)
    public void saveAnnotation(User user) {
        userDao.save(user);
        exceptionMethod();
        roleService.save(user.getRole());
    }

    private void exceptionMethod() {
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            throw new ArithmeticException("运算异常");
        }
    }

四.不正确的传播行为

如果传播行为使用的是NOT_SUPPORTED,那么事物无法回滚。NOT_SUPPORTED表示当前方法不应该有事务,如果有事务存在,将它挂起,以无事务状态运行。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Transactional(propagation = Propagation.NOT_SUPPORTED)

五.方法修饰为private

如果方法以private修饰,那么方法将不会被代理,事物自然不会生效,不过如果在进行业务开发的时候,对于需要其它类进行调用的方法,我们都是以public修饰,因为如果以private修饰,其它类想要访问的话需要借助反射才能访问,在IDEA中,@Transactional方法如果修饰为private,会有错误提醒,但是运行不会报错。

不过一些场景我们可能需要反射调用,所以不应该避开这个问题,还是将其修饰为public。

六.数据库不支持事物

如果数据库不支持事物,那么即使项目中使用了Spring事物,也不会生效,因为Spring的事物最终也是JDBC的事物,JDBC事物也要数据库支持事物才行,MySQL中MyISAM存储引擎不支持事物,InnoDB才支持事物。

七.没有配置事务管理器,导致事务失效。

使用非SpringBoot项目,需要配置PlatformTransactionManager,需要加上@EnableTransactionManagement注解,如果是SpringBoot项目,那么可以不用配置,因为SpringBoot默认帮我们装配好了,我们直接使用就好。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 刘牌 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring事务失效场景
如果@Transactional 没有特别指定,Spring 只会在遇到运行时异常RuntimeException或者error时进行回滚,而IOException等检查异常不会影响回滚。
科技新语
2022/12/22
4200
Spring事务失效场景
每日一博 - 常见的Spring事务失效&事务不回滚案例集锦
在事务方法add中,直接调用事务方法updateStatus。 updateStatus方法拥有事务的能力是因为spring aop生成代理了对象,但是这种方法直接调用了this对象的方法,所以updateStatus方法不会生成事务。
小小工匠
2021/09/08
1.5K0
Spring事务失效的12种场景总结
上面代码中我们可以看到对于方法add的访问修饰符被定义成了private,这样会导致事务失效,原因是Spring 要求被代理的方法必须是 **public** 的。简单粗暴来看源码是怎么搞的。如下:
@派大星
2023/06/28
6.2K0
Spring事务失效的12种场景总结
阿里四面:你能让Spring@Transactional注解在事务下不生效吗?
然后我们还需要一个Dao,来操作user表。在 site.nemo.dao 包下新建一个UserDao类:
Java程序猿
2021/06/08
3810
说吧,有没有被Spring事务坑过
新来的实习生找我吐槽,在开发过程中,经常遇到事务失效的问题,了不起实在看不下去了,整理了一份事务失效的N种情况,让他学习学习。
灬沙师弟
2023/05/18
3380
说吧,有没有被Spring事务坑过
@Transactional注解使用以及事务失效的场景
数据库事务,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
政采云前端团队
2023/09/28
2K0
@Transactional注解使用以及事务失效的场景
详细整理Spring事务失效的具体场景及解决方案
实际项目开发中,如果涉及到多张表操作时,为了保证业务数据的一致性,大家一般都会采用事务机制;好多小伙伴可能只是简单了解一下,遇到事务失效的情况,便会无从下手,溪源此篇文章给大家整理了一下常见Spring事务失效的场景,希望开发过程尽量避免踩坑,造成时间精力的浪费。 溪源按照最基本的使用方式以及常见失效场景优先级整理,先简单介绍一下具体失效场景:
沁溪源
2020/09/02
1.2K0
spring事务失效的几种场景以及原因
spring事务失效场景可能大家在很多文章都看过了,所以今天就水一篇,看大家能不能收获一些不一样的东西。直接进入主题
lyb-geek
2022/03/01
2.3K0
spring事务失效的几种场景以及原因
SpingBoot:事务@Transactional注解不生效场景简介及事务回滚
声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
Freedom123
2024/03/29
4720
SpingBoot:事务@Transactional注解不生效场景简介及事务回滚
spring事务失效的几种情况与原因
失效原因: spring事务只有捕捉到了业务抛出去的异常,才能进行后续的处理,如果业务自己捕获了异常,则事务无法感知。
终有救赎
2023/10/16
2420
Spring @Transactional事务管理
事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。
鱼找水需要时间
2023/02/16
4230
Spring事务异常回滚需要数据库引擎支持
例:一个方法报异常,另一个方法回滚 在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理
似水的流年
2019/12/05
9300
面试必问|哪些场景下Spring的事务会失效?
在日常工作中,如果对Spring的事务管理功能使用不当,则会造成Spring事务不生效的问题。而针对Spring事务不生效的问题,也是在跳槽面试中被问的比较频繁的一个问题。
冰河
2021/12/20
2840
面试必问|哪些场景下Spring的事务会失效?
Transactional注解不生效案例
参考:Spring中propagation的7种事务配置_sayoko06的博客-CSDN博客_propagation
CBeann
2023/12/25
3740
Transactional注解不生效案例
SpringBoot 系列教程之事务不生效的几种 case
前面几篇博文介绍了声明式事务@Transactional的使用姿势,只知道正确的使用姿势可能还不够,还得知道什么场景下不生效,避免采坑。本文将主要介绍让事务不生效的几种 case
一灰灰blog
2020/02/18
7730
SpringBoot 系列教程之事务不生效的几种 case
探究Spring事务:了解失效场景及应对策略
在现代软件开发中,数据的一致性和完整性是至关重要的。为了保证这些特性,Spring框架提供了强大的事务管理机制,让开发者能够更加自信地处理数据库操作。然而,事务并非银弹,存在一些失效的情景,本文将带您深入探究Spring事务及其失效场景,并为您呈现应对策略。
修己xj
2023/08/25
2580
探究Spring事务:了解失效场景及应对策略
Spring声明式与编程式事务的区别,事务与非事务方法相互调用导致的事务不生效问题
序号 参数 含义 1 原子性(Atomicity) 事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。 2 一致性(Consistemcy) 事务前后,数据库的状态都满足所有的完整性约束。 3 隔离性(Isolation) 并发执行的事务是隔离的,一个不影响一个。通过设置数据库的隔离级别,可以达到不同的隔离效果 4 持久性(Durability) 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
chenchenchen
2022/03/09
1.4K0
Spring声明式与编程式事务的区别,事务与非事务方法相互调用导致的事务不生效问题
聊聊Spring事务控制策略以及@Transactional失效问题避坑
在大部分涉及到数据库操作的项目里面,事务控制、事务处理都是一个无法回避的问题。比如,需要对SQL执行过程进行事务的控制与处理的时候,其整体的处理流程会是如下的示意:
是Vzn呀
2022/08/26
5530
Spring Boot 的事务控制及示例代码
Spring Boot 提供了简单易用的事务控制功能,方便开发者进行数据库操作时保证数据的一致性和完整性。本文将介绍 Spring Boot 事务控制的用法和应用场景,并提供丰富的例子。
万猫学社
2023/09/01
6340
Spring Boot 的事务控制及示例代码
Spring事务详解
最近在项目组的业务技术分析会上,有同事遇到事务的失效的场景导致线上业务不可用。如果对Spring事务的@Transactional理解有限的话,确实很容易在开发中忽视一些细节问题,导致业务不可用的Bug。既然发生了问题,那么必然是要总结和反省的,然后我今天这里有时间总结一下各种事务失效的问题。
麋鹿大哥
2020/11/09
9330
推荐阅读
相关推荐
Spring事务失效场景
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验