You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot从CSV导入JPA记录报错:行被其他事务修改/删除

解决SpringBoot CSV导入News数据时的ObjectOptimisticLockingFailureException问题

核心原因分析

这个异常本质是乐观锁冲突:你的News实体类大概率带有@Version注解的乐观锁字段,导入过程中要么是同一行数据被重复操作,要么是字段值(比如version)与数据库预期不符,触发了乐观锁校验失败。

具体排查与解决步骤

1. 检查News实体类的乐观锁配置

  • 如果实体类中有@Version注解的字段(比如private Integer version;):
    • 若为初始化数据场景,可临时给每条导入的News对象设置初始version值(如news.setVersion(0);),确保和数据库的初始校验逻辑匹配。
    • 若不需要在导入阶段启用乐观锁,可临时移除@Version注解(导入完成后再恢复),或者在导入代码中通过实体管理器禁用乐观锁校验。

2. 校验CSV文件内容

  • 检查CSV的id列是否存在重复值:重复的id会导致多次尝试插入/更新同一行数据,引发乐观锁冲突。
  • 若CSV包含version列,确保值符合数据库规则(新记录设为0,更新已有记录则要与数据库当前version一致);若没有version列,在代码中统一给导入对象设置初始version。

3. 修正数据初始化代码

  • 避免复用实体对象:确保每处理一行CSV数据都创建新的News实例,不要循环复用同一个对象,否则多次保存时version字段无法自动更新,触发校验失败。
  • 控制事务与数据操作逻辑:
    • 若为初始化数据,建议先清空News表(newsRepository.deleteAll();),再批量导入(newsRepository.saveAll(newsList);),避免与已有数据冲突。
    • 检查是否存在多事务并发操作News表的情况(比如其他初始化任务、定时任务),暂停这些操作后再执行导入。

示例修正代码

假设你的导入逻辑如下,可调整为:

// 读取CSV数据
List<News> newsList = csvReader.parseCsvFile("news_data.csv");

// 初始化乐观锁字段(如果实体类有@Version)
newsList.forEach(news -> news.setVersion(0));

// 清空已有数据(仅初始化场景使用)
newsRepository.deleteAllInBatch();

// 批量保存
newsRepository.saveAllAndFlush(newsList);

内容的提问来源于stack exchange,提问作者Gwendal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:09:49