遇到Spring事务失效,你该怎么办?

news2024/10/6 8:21:42

Spring 事务场景失效是一个常见的问题。今天来分析这个问题。

在这里插入图片描述

1、事务方法被final、static关键字修饰,方法访问权限不是public

@Service
public class UserService {
    
    @Autowired
    private UserDao userDao;

    // final修饰的事务方法
    @Transactional
    public final void addUser(User user) {
        userDao.addUser(user);
    }

    // 访问权限不是public的事务方法
    @Transactional
    protected void updateUser(User user) {
        userDao.updateUser(user);
    }

    // 静态方法的事务方法
    @Transactional
    public static void deleteUser(int userId) {
        userDao.deleteUser(userId);
    }
}

失效原因

  1. 事务方法被final、static关键字修饰:这是因为Spring事务的实现依赖于AOP技术,而final、static方法无法被代理,因此在这些方法中调用事务方法,事务无法生效。
  2. 方法访问权限不是public:Spring事务的实现也是基于AOP的,所以在非public的方法中调用事务方法,无法触发AOP代理,因此事务不会生效。

2、同一个类中,方法内部调用

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @Transactional
    public void addUser(User user) {
        // 事务方法内部调用了updateUser方法,事务失效
        updateUser(user);
    }

    public void updateUser(User user) {
        userDao.updateUser(user);
    }
}

失效原因
在同一个类中,事务方法内部调用其他方法时,可能会导致事务失效。这是因为Spring的事务是基于AOP(面向切面编程)实现的,在同一个类中的方法内部调用其他方法时,实际上是调用的类的内部方法,而不是通过代理调用方法,从而导致事务无法生效。

3、事务注解配置错误

  • 没有开启事务注解扫描或者没有在配置文件中开启事务。
<!-- 开启事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- 开启事务注解扫描 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
  • 没有在需要开启事务的方法上添加@Transactional注解。
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Transactional
    public void addUser(User user) {
        userDao.addUser(user);
    }
}
  • 在事务方法上添加了错误的propagation或isolation属性值。
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public void transferMoney(String fromAccount, String toAccount, double amount) {
    // transfer money from one account to another
}

  • 在注解中配置了错误的rollbackFor或noRollbackFor属性值。
@Transactional(rollbackFor = RuntimeException.class, noRollbackFor = BusinessException.class)
public void updateUserInfo(User user) throws BusinessException {
    // update user information
}

4、 事务注解被覆盖导致事务失效

@Transactional(propagation = Propagation.REQUIRED)
public class ParentClass {
    public void doSomething() {
        // ...
    }
}

public class ChildClass extends ParentClass {
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void doSomething() {
        // ...
    }
}

在上述代码中,ParentClass 中的事务注解 @Transactional(propagation = Propagation.REQUIRED) 覆盖了 ChildClass 中的事务注解 @Transactional(propagation = Propagation.NOT_SUPPORTED),因此当调用 ChildClass 中的 doSomething 方法时,事务将会失效。为了解决这个问题,可以在子类中将事务注解的属性值与父类保持一致。

5、 嵌套事务和异常被捕获导致事务失效

嵌套事务是指在一个事务内部,开启了一个新的事务,这个新事务与外部事务是嵌套关系,也就是内部事务依赖于外部事务,只有外部事务提交成功,内部事务才能生效。

在 Spring 中,通过设置事务传播级别来实现嵌套事务,常见的传播级别包括:

  • REQUIRED:如果当前存在事务,则加入该事务;否则,创建一个新的事务。这是默认值。
  • REQUIRES_NEW:每次都创建一个新的事务,并将当前事务挂起。
  • NESTED:如果当前存在事务,则在嵌套事务内执行;否则,创建一个新的事务。这种方式也是嵌套事务的实现方式。
    在嵌套事务中,如果外部事务回滚了,那么内部事务也会回滚;如果内部事务回滚了,只会回滚内部事务,而不会影响到外部事务。

然而,使用嵌套事务需要注意一些坑:

  1. 数据库支持
    嵌套事务是由数据库来实现的,不同的数据库对于嵌套事务的支持不同,有些数据库甚至不支持嵌套事务,例如 MySQL 默认是不支持嵌套事务的。

  2. 事务管理器
    Spring 事务是通过事务管理器来实现的,不同的事务管理器对于嵌套事务的支持也不同,如果使用的事务管理器不支持嵌套事务,那么嵌套事务就会失效。

  3. 异常处理
    在嵌套事务中,如果内部事务抛出了异常,并且外部事务没有捕获这个异常,那么整个事务会回滚,包括内部事务和外部事务。因此,在嵌套事务中,要注意异常处理。

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateUser(User user) {
        jdbcTemplate.update("update user set name = ? where id = ?", user.getName(), user.getId());
        try {
            insertLog(user.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Transactional(propagation = Propagation.NESTED)
    public void insertLog(Long userId) {
        jdbcTemplate.update("insert into log(user_id) values(?)", userId);
        throw new RuntimeException("插入日志失败");
    }

}

上述代码中,updateUser 方法中调用了 insertLog 方法,insertLog 方法使用了 Propagation.NESTED 的传播级别来实现嵌套事务。当插入日志时,会抛出 RuntimeException 异常,并被 updateUser 方法中的 try-catch 块捕获。在这种情况下,虽然 insertLog 方法的事务会回滚,但是由于使用的是嵌套事务,所以 updateUser 方法的事务并不会回滚,导致了事务失效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/443676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实时分布式低延迟OLAP数据库Apache Pinot探索实操

文章目录 概述定义特性何时使用 部署Local安装快速启动手动设置集群 Docker安装快速启动手动启动集群Docker Compose 实操批导入数据流式导入数据 概述 定义 Apache Pinot 官网地址 https://pinot.apache.org/ 最新版本0.12.1 Apache Pinot 官网文档地址 https://docs.pinot.a…

Vivado如何清理工程,并避免缺失必要的文件?

FPGA开发是一项非常复杂的工作&#xff0c;需要处理大量的代码、约束和仿真文件。在开发过程中&#xff0c;由于文件数量庞大&#xff0c;很容易导致工程变得混乱不堪。Vivado是Xilinx公司推出的一款FPGA开发工具&#xff0c;能够帮助开发人员处理这种复杂性&#xff0c;提高开…

【FPGA-DSP】第七期:Mcode调用

目录 1. 有限状态机设计 1.1 FSM代码编写 1.2 输入序列代码编写 1.3. mcode概念 2. Simulink 2.1. 输入部分 2.2. Mcode模块 2.3. 完整模块 总结 参考博客【R1】&#xff0c;参考视频资料【R2】 设计中经常用到一些控制逻辑&#xff0c;如有限状态机&#xff08;FS…

语音特征参数MFCC提取过程详解

一、MFCC概述 在语音识别&#xff08;SpeechRecognition&#xff09;和话者识别&#xff08;SpeakerRecognition&#xff09;方面&#xff0c;最常用到的语音特征就是梅尔倒谱系数&#xff08;Mel-scaleFrequency Cepstral Coefficients&#xff0c;简称MFCC&#xff09;。根据…

IntelliJ IDEA全新发布v2023.1——全面增强UI体验和性能!

IntelliJ IDEA&#xff0c;是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能可以说是超常的。 I…

javaSwingrsa和aes混合加密文件传输系统

RSA和AES加密混合文件传输系统 环境要求&#xff1a; 1、java1.8 2、socket 3、mysql 4、io流 5、swing 登录界面 客户端登录&#xff1a; 1.用户注册的账号保存到数据库中&#xff0c;用户的密码经过md5后保存到数据库中。 2.用户输入正确的账号和密码可以进入 “ …

Gulp 打包压缩 js 文件到指定目录详细流程(修改文件名与后缀)

主篇 前端 Gulp 详细介绍与案例使用。 打包 index.js 测试内容 js 包内容文件&#xff1a; // 测试属性 export const dzmName dzm export const dzmAge 18// 测试方法 export function dzmFunc (name, age) {return 名字&#xff1a;${name}&#xff0c;年龄&#xff1a;${…

Chat的提问工程师,要上线了你慌不慌?

一、什么是Prompt? (1)Prompt的概念 我们在使用GPT的时候,给GPT发送的消息就是Prompt. 例如,当我们问ChatGPT"WPS是什么软件?"时: 其中,"WPS是什么软件?"这句话就是Prompt. (2)为什么要学习Prompt? Prompt是我们和GPT交流的方式,我们需要让GPT了解…

微信小程序从零开始经验贴(含详细资料及链接)

背景: 从事微信小程序开发近3年&#xff0c;现在几乎能独当一面&#xff0c;对后台程序也有一定研究。      我学习的基础是c编程经验&#xff0c;对前端、后端没有太多涉及。微信小程序相关资料都是自己找的&#xff0c;然后在项目中看别人的代码&#xff0c;摸着石头过河…

什么是单例模式?

文章目录 01 | 什么是单例模式&#xff1f;02 | 实现懒汉式饿汉式 03 | 总结 每一次实验课都要把上一节课的实验报告打印出来&#xff0c;交作业&#xff0c;这个时候的打印店总是很多人&#xff0c;这时候打印机就那么几台&#xff0c;粥少僧多的情况下&#xff0c;打印机怎么…

动态路由的原理与配置

一.动态路由介绍 1.动态路由选择 指路由器使用路由选择协议来获悉网络并更新路由选择表。 2.路由协议分类 3.管理距离介绍 管理距离&#xff08;AD&#xff09;用于判断从邻接路由器收到的路由选择信息的可信度&#xff0c;它是 0-255的整数&#xff0c;0 表示可信度最大&#…

Android9 Settings源码导入Android Studio查看并调试

Android9 Settings源码导入Android Studio查看并调试 本次调试在已编译的工程下 1. 导入packages/app/settings 不要直接导入这个模块&#xff0c;导入上一级app目录 在选择时选择Settings相关所有目录&#xff0c;如下 如下这里的sdk配置是我已经添加的&#xff0c;后面可…

用了这几个方法,Facebook广告转化真上去了!

随着全球电商市值的猛涨&#xff0c;Facebook广告的价值再次被放大。然而&#xff0c;在Facebook上的广告资源竞争日益激烈的情况下&#xff0c;即使你有最好的广告策略和投放预算&#xff0c;如果你的广告创意不能吸引潜在客户的注意&#xff0c;那么你的广告投放也可能失败。…

at单一次任务,crontab周期性任务 rhce(21)

目录 1.atd和crond两个任务管理程序的区别 2.指定在2023/08/26 09:00将时间写入testmail.txt文件中 3.指定在每天凌晨4:00将该时间点之前的系统日志信息备份到个目录下&#xff08;/var/log/messages&#xff09;&#xff0c;备份后日志文件名显示格式logfileYY-MM-DD HH-MM…

08-java之io流基础

io流学习流程 说白了&#xff0c;本节的目的就是对 文件增删改查&#xff0c;先说一下学习顺序吧 定位文件 File类可以定位文件&#xff1a;可以进行删除文件内容&#xff0c;读取文件本身信息等操作&#xff0c;但是不能读写文件内容 字符集 想要读取文件中的数据&#xff0…

Nginx+Tomcat负载均衡、动静分离

1.Tomcat多实例部署 Tomcat的多实例部署简单的讲就是基于端口的虚拟主机设置 步骤一&#xff1a;安装jdk (1&#xff09;关闭防火墙和selinux&#xff0c;防止其对安装过程的干扰 &#xff08;2&#xff09;将准备好的软件包拖入/opt目录下&#xff0c;进行安装 #某rpm包尚未…

【HCIP】BGP实验(联邦,路由反射器,手工汇总)

目录 需求&#xff1a; Ⅰ、IP规划 Ⅱ、配置IP与做通IGP(用的ospf) Ⅲ、开启BGP协议 Ⅳ、AS1、AS3的10...环回互相通讯 Ⅴ、对路由表进行汇总 Ⅵ、回望需求 需求&#xff1a; 1.AS1存在两个环回&#xff0c;一个地址为192.168.1.0/24该地址不能在任何协议中宣告 AS3存在两…

马斯克的Starship,除了“大”还有什么呢?

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 种种迹象表明&#xff0c;由ChatGPT引发的算力军备竞赛已经悄然而至了。 终于&#xff0c;到了检验人类最大火箭发射的时候了。 2023年4月17日&#xff0c;SpaceX将其大型深空火箭Starship发射升空&#xff0c;发射地点为Sp…

CANoe使用记录(三):CANoe发送报文设置

目录 1、概述 2、报文发送 2.1、interactive generators&#xff08;交互生成器&#xff09; 2.2、重命名发送报文 2.3、增加报文 2.4、触发方式 2.5、从DBC导入报文 2.6、设置信号值 1、概述 很大一部分时候&#xff0c;在控制零部件时候&#xff0c;需要发送报文到下…

辉煌优配|军工板块逆市上涨,16只概念股已披露一季度业绩预喜

今日&#xff0c;军工股逆市上涨。 4月21日&#xff0c;A股三大股指低开低走&#xff0c;半导体、AI使用、信创工业、软件等科技属性概念领跌&#xff0c;国防军工、食品饮料和电力设备等板块上涨。 工业互联网中心工业规模超1.2万亿元 据央视新闻报道&#xff0c;本年是《工业…