【Bug】定时任务中 Jpa Save 方法失效

【Bug】定时任务中 Jpa Save 方法失效

首先说一下问题,在定时任务中调用 jpa 的 save 方法没有效果,但是通过外界调用,比如 controller 中注入 service 来调用是可以的,真是巨巨巨离谱,我被折磨了好几天。

我这个问题的根源在于多数据源的配置上,所以如果你的项目中没有使用多数据源,那接下来的内容应该对你没什么帮助了~

一般来讲,在配置多数据源的时候,除了要继承 AbstractRoutingDataSource 类

package com.xsdl.content;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class MultiDataSource extends AbstractRoutingDataSource {private static final ThreadLocal<String> keys = new ThreadLocal<String>();@Overrideprotected Object determineCurrentLookupKey() {return keys.get();}public static void setDataSource(String dataSource) {keys.set(dataSource);}public static String getDatasource() {return keys.get();}public static void clearDataSource() {keys.remove();}}

还会配置对应数据源的 datasource、jdbcTemplate 等

package com.xsdl.config;import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@Configuration
public class MultiDataSourceConfig {@Bean(name = "dataSourceAAA")@Primary@ConfigurationProperties("spring.aaa.datasource")public DataSource dataSourceAAA() {return DataSourceBuilder.create().build();}@Bean(name = "dataSourceBBB")@ConfigurationProperties("spring.bbb.datasource")public DataSource dataSourceBBB() {return DataSourceBuilder.create().build();}@Bean(name = "multiDataSource")public MultiDataSource multipleDataSource(@Qualifier("dataSourceAAA") DataSource dataSourceA,@Qualifier("dataSourceBBB") DataSource dataSourceB) {Map<Object, Object> map = new HashMap<>();map.put("dataSourceA", dataSourceA);map.put("dataSourceB", dataSourceB);MultiDataSource multipleDataSource = new MultiDataSource();multipleDataSource.setDefaultTargetDataSource(dataSourceA);multipleDataSource.setTargetDataSources(map);return multipleDataSource;}@Beanpublic JdbcTemplate jdbcTemplate(MultiDataSource multipleDataSource) {return new JdbcTemplate(multipleDataSource);}@Bean@Primary@Description("事务管理器")public PlatformTransactionManager transactionManager(@Qualifier("multiDataSource") MultiDataSource multiDataSource) {return new DataSourceTransactionManager(multiDataSource);}}

事情到现在是很正常的,启动项目也可以正常启动,正常在 service 的业务逻辑里调用对应的 dao 或者 repository 去保存数据也可以

突然有一天,我接到一个需求,有一个接收记录的表,我需要定时从中查询执行失败的,重试进行补偿,那我补偿完成后,当然要更新回去对吧,于是我写了一个类似下面这样的代码:

package com.xsdl.job;import com.xsdl.dao.UserDao;
import com.xsdl.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.util.UUID;
import java.util.stream.IntStream;@Component("tsJob")
@Slf4j
public class TsJob {@Autowiredprivate UserDao userDao;@Scheduled(cron = "0 0/2 * * * ?")public void execute() {log.warn("定时任务开始执行");IntStream.rangeClosed(1, 10).forEach(i -> {User user = new User();user.setUuid(UUID.randomUUID().toString());user.setName("name" + i);userDao.save(user);});log.warn("定时任务执行结束");}}

具体逻辑不用关注,就是查数据库,然后修改了几个字段,重新 save 回去,这时候问题出现了,save 方法执行无效,数据库里数据没更新,我一路 debug,期间各种磕磕绊绊,就是找不到问题,反而找到了几个同病相怜的人:

[在spring的定时任务中使用 jpa 的save 方法失效](https://forum.springdoc.cn/t/topic/776)

no transaction is in progress

我一开始以为是事务的开启问题,包括但这样尝试:

    @Scheduled(cron = "0 0/2 * * * ?")public void execute() {log.warn("定时任务开始执行");IntStream.rangeClosed(1, 10).forEach(i -> {User user = new User();user.setUuid(UUID.randomUUID().toString());user.setName("name" + i);getThis.doSave(user);});log.warn("定时任务执行结束");}@Transactional(propagation = Propagation.New)public void doSave(User user) {userDao.save(user);}private TsJob getThis() {return ApplicationContextUtil.getBean("tsJob",TsJob.class);}

然而什么用都没有

最关键的是,这个方法如果在一个 controller 里手动调用是可以执行的,我觉得太离谱了,就想开个新项目复现一下,结果怎么都复现不出来,最后突然觉得区别也就是在多数据源上了,中间各种尝试,直到我把这个代码注释掉,终于可以了~

    @Bean@Primary@Description("事务管理器")public PlatformTransactionManager transactionManager(@Qualifier("multiDataSource") MultiDataSource multiDataSource) {return new DataSourceTransactionManager(multiDataSource);}

如果你的项目里也这样配置了 transactionManager ,可能就是这个问题~

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

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

相关文章

【Redis】热点key问题,的原因和处理,一致性哈希,删除大key的方法

热点 Key 指单个 Key 被高并发访问&#xff08;如爆款商品&#xff09;&#xff0c;导致 Redis 压力骤增。解决方案应针对 “单个 Key 高并发”&#xff1a; 分片缓存&#xff1a;将热点 Key 分散到不同 Redis 节点&#xff08;如按一致性哈希算法分片&#xff09;。本地缓存&…

通过远程桌面连接Windows实例提示“出现身份验证错误,无法连接到本地安全机构”错误怎么办?

本文介绍通过远程桌面连接Windows实例提示“出现身份验证错误无法连接到本地安全机构”错误的解决方案。 问题现象 通过本地电脑内的远程桌面连接Windows实例提示“出现身份验证错误&#xff0c;无法连接到本地安全机构”错误。 问题原因 导致该问题的可能原因如下&#x…

[python] argparse怎么指定bool类型?

前述 最近在写脚本的时候想要实现一个if 操作&#xff0c;通过用户输入。确定要不要启用某个语句。 非常自然的就是使用python的argparse包&#xff0c;但是发现了一个陷阱&#xff0c;记录下。 陷阱 argparse.ArgumentParser() 可以指定输入类型&#xff0c;我可以设定为bo…

Rust 学习笔记:迭代器

Rust 学习笔记&#xff1a;迭代器 Rust 学习笔记&#xff1a;迭代器Iterator trait 和 next 方法使用迭代器的方法生成其他迭代器的方法使用闭包捕获它们的环境 Rust 学习笔记&#xff1a;迭代器 在 Rust 中&#xff0c;迭代器负责遍历每个项的逻辑。迭代器是懒惰的&#xff0…

【深度剖析】义齿定制行业数字化转型模式创新研究(上篇2:痛点和难点分析)

数字化转型正在重塑义齿行业的生态格局,但也面临技术融合与模式变革的深层挑战。当前,义齿定制行业正处于从传统手工制造向全流程数字化制造转型的关键阶段。3D扫描、CAD/CAM(计算机辅助设计与制造)、3D打印等技术的广泛应用,显著提升了义齿制作的精度和效率。传统石膏模型…

window安装nginx

步骤1&#xff1a;下载Nginx for Windows​ 访问Nginx官网下载页面&#xff1a;https://nginx.org/en/download.html 在​​Stable version​​&#xff08;稳定版&#xff09;下找到Windows版本&#xff0c;点击下载.zip文件&#xff08;如 nginx-1.28.0.zip&#xff09; 步…

气象算法工程师学习路径

目录 &#x1f324;️ 气象学与数值预报基础课程&#x1f916; 气象人工智能与数据分析课程&#x1f4d8; 进阶与实战课程推荐&#x1f9ed; 学习建议与路径规划 如果希望成为一名气象算法工程师&#xff0c;并寻找深入浅出、理论与实践结合的学习资源&#xff0c;以下是为你精…

回调函数的理解

int yuxiangrousi 0; // 全局变量&#xff1a;鱼香肉丝&#xff08;酱油量&#xff09;// 回调函数&#xff1a;妈妈处理酱油&#xff08;将酱油加入鱼香肉丝&#xff09; void mother_callback(int new_jiangyou) {yuxiangrousi new_jiangyou; // 把酱油放进鱼香肉丝 }// 孩…

多部手机连接同一wifi的ip一样吗?如何更改ip

通常情况下&#xff0c;多部手机连接同一个WiFi时&#xff0c;它们的IP地址是各不相同的&#xff08;在局域网内&#xff09;。但是&#xff0c;从互联网&#xff08;外网&#xff09;的角度看&#xff0c;它们共享同一个公网IP地址。让我详细解释一下&#xff0c;并说明如何更…

环境温度通过H2A.Zub和H3K27me3动态调控拟南芥细胞命运决定

2025年4月22日&#xff0c;中国科学院遗传与发育生物学研究所肖军研究组在Developmental Cell在线发表了题为Dynamic control of H2A.Zub and H3K27me3 by ambient temperature during cell fate determination in Arabidopsis的研究论文&#xff0c;本研究综合运用ChIP-seq、C…

2024 吉林 CCPC

文章目录 2024 吉林 CCPCL. Recharge&#xff08;思维、分配&#xff09;G. Platform Game(模拟)E. Connect Components (排序、思维)D. Parallel Lines 2024 吉林 CCPC 题目链接&#xff1a; Dashboard - The 2024 CCPC National Invitational Contest (Changchun) , The 17…

day13 leetcode-hot100-24(链表3)

234. 回文链表 - 力扣&#xff08;LeetCode&#xff09; 1.转化法 思路 将链表转化为列表进行比较 复习到的知识 arraylist的长度函数&#xff1a;list.size() 具体代码 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode ne…

Vim文本编辑器快捷键用法以及简单介绍

目录 vim文本编辑器 简介&#xff1a; 语法&#xff1a; vim模式介绍&#xff1a; 模式切换&#xff1a; 用法&#xff1a; 编辑模式&#xff1a; 一般模式&#xff1a; 命令模式&#xff1a; vim文本编辑器 简介&#xff1a; 在命令行界面下&#xff0c;最常用的文本…

从 0 到 1:Spring Boot 与 Spring AI 深度实战(基于深度求索 DeepSeek)

在人工智能技术与企业级开发深度融合的今天&#xff0c;传统软件开发模式与 AI 工程化开发的差异日益显著。作为 Spring 生态体系中专注于 AI 工程化的核心框架&#xff0c;Spring AI通过标准化集成方案大幅降低 AI 应用开发门槛。本文将以国产大模型代表 ** 深度求索&#xff…

[Windows] 摸鱼小工具:隐藏软件(重制版)

由吾爱大神写的摸鱼工具&#xff1a; 数据存放路径为C:\Users\用户名\AppData\Local\HideSoft&#xff0c;如果不想用时&#xff0c;删除软件及此路径下的HideSoft文件夹。如添加了开机启动&#xff0c;删除启动菜单文件夹的快捷方式即可&#xff0c;或者删除前在软件中取消设置…

C++ 判断文件的编码类型

大多数文本编辑器&#xff0c;都会在文本文件的头部插入一部分特殊的字节&#xff0c;用于辅助文本编辑器来判断该文件的字符集编码类型。 如&#xff1a;记事本 目前支持的字符集类型&#xff0c;通常为三种&#xff1a; Unicode、UTF8、UnicodeBIG、CP_ACP&#xff08;默认…

时间序列噪声模型分析软件推荐与使用经验

最近在论文大修2024年投稿的一篇文章&#xff0c;大修了2轮&#xff0c;最后一次还是重新投稿&#xff0c;其中有一个问题一直被审稿人怼&#xff0c;他认为我计算时间序列的趋势的时候&#xff0c;没有考虑时间的相关性&#xff0c;即对噪声模型的估计不合理&#xff0c;会影响…

【redis实战篇】第六天

摘要&#xff1a; 本文介绍了基于Redis的秒杀系统优化方案&#xff0c;主要包含两部分&#xff1a;1&#xff09;通过Lua脚本校验用户秒杀资格&#xff0c;结合Java异步处理订单提升性能&#xff1b;2&#xff09;使用Redis Stream实现消息队列处理订单。方案采用Lua脚本保证库…

【Java Web】速通HTML

参考笔记: JavaWeb 速通HTML_java html页面-CSDN博客 目录 一、前言 1.网页组成 1 结构 2 表现 3 行为 2.HTML入门 1 基本介绍 2 基本结构 3. HTML标签 1 基本说明 2 注意事项 4. HTML概念名词解释 二、HTML常用标签汇总 + 案例演示 1. 字体标签 font (1)定义 (2)案例 2…

Oracle/openGauss中,DATE/TIMESTAMP与数字日期/字符日期比较

ORACLE 运行环境 openGauss 运行环境 0、前置知识 ORACLE&#xff1a;DUMP()函数用于返回指定表达式的数据类型、字节长度及内部存储表示的详细信息 SELECT DUMP(123) FROM DUAL; -- Typ2 Len3: 194,2,24 SELECT DUMP(123) FROM DUAL;-- Typ96 Len3: 49,50,51 -- ASCII值&am…