当前位置: 首页 > news >正文

多线程下,@Transactional失效解决

一、问题复现

批量插入时,使用多线程对插入数据实现分批插入,在service层使用@Transactional注解,对应方法中线程池中开辟的子线程抛出异常时,没有回滚事务。

二、原因分析

事务管理范围不正确:@Transactional注解仅对当前方法有效,如果在方法内创建新的线程或使用线程池等异步操作,该方法之外的代码将无法受到事务的管理。因此,在使用多线程进行批量操作时,需要确保整个批量操作处于同一事务管理范围内。

Spring事务和Java线程池机制的互动问题:在使用ThreadPoolExecutor进行批量操作时,线程池中的线程和Spring管理的事务并不是同一个线程,这可能会导致事务管理器感知不到线程中的异常,从而导致事务未能回滚。

三、解决办法

弃用注解样事务,改为手动管理事务。

复制代码

  SqlSession sqlSession = SpringContextUtils.getBean(SqlSessionTemplate.class).getSqlSessionFactory() .openSession();Connection connection = sqlSession.getConnection();OfflineExpressRecordExtMapper extMapper = sqlSession.getMapper(OfflineExpressRecordExtMapper.class);// 批量插入int taskCount = (int) Math.ceil((double) beanList.size() / THREAD_HANDLE);ThreadPoolExecutor executor = SpringContextUtils      .getBean("offlineExpressRecordThreadPoolExecutor", ThreadPoolExecutor.class);
try {
connection.setAutoCommit(false);
ArrayList<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < taskCount; i++) {
int start = i * THREAD_HANDLE;
int end = (i + 1) * THREAD_HANDLE > beanList.size() ? beanList.size() : (i + 1) * THREAD_HANDLE;
List<OfflineExpressRecord> threadHandleList = beanList.subList(start, end);
Future<?> task = executor.submit(() -> extMapper.saveBatch(threadHandleList));
futures.add(task);
}// 等待插入完成,检验异常
for (Future<?> future : futures) {
future.get();
}connection.commit();} catch (Exception e) {log.error("批量导入存储数据过程中出现异常", e);connection.rollback();throw e;
} finally {connection.close();}
http://www.lryc.cn/news/458211.html

相关文章:

  • PyCharm 项目解释器切换指南:如何在项目中更换 Python Interpreter
  • STM32F407寄存器操作(DMA+SPI)
  • Oracle 的 OCP 与 MySQL 的 OCP 的区别
  • 数据治理、数据清洗定义、区别以及数据清洗常用方法
  • web基础-攻防世界
  • Java基础-String Class(字符串类)
  • 《Linux服务与安全管理》| 服务进程与网络配置
  • No.15 笔记 | CSRF 跨站请求伪造
  • 解决linux中pip速度过慢问题
  • FlinkSQL中 的 双流JOIN
  • Mysql(五) --- 数据库设计
  • po框架的了解和应用
  • Linux云计算 |【第四阶段】RDBMS2-DAY5
  • 从0开始深度学习(9)——softmax回归的逐步实现
  • Cannot inspect org.apache.hadoop.hive.serde2.io.HiveDecimalWritable 问题分析处理
  • 电子取证新视角:USB键盘流量提取密码方法研究与实现
  • Tongweb7049m4+THS6010-6012配置故障轉移+重試机制(by lqw)
  • 在线客服系统网站源码-网页聊天客服实现代码
  • JioNLP:一款实用的中文NLP预处理工具包
  • GR-ConvNet论文 学习笔记
  • windows环境批量删除指定目录下的全部指定文件
  • 水深探测仪的作用和使用方法
  • Leetcode 搜索插入位置
  • jsp怎么实现点赞功能
  • 取消microsoft edge作为默认浏览器 ,修改方法,默认修改不了的原因
  • C++面试速通宝典——17
  • 10、论文阅读:基于双阶对比损失解纠缠表示的无监督水下图像增强
  • Git配置token免密登录
  • 活动预告|博睿数据将受邀出席GOPS全球运维大会上海站!
  • Flutter技术学习