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

MySQL存储数据会丢失吗?JDBC插入返回行数是否可能不符合预期?

结论

就算不用INSERT IGNORE INTO语法,这段示例里执行插入2条数据的普通INSERT语句时,返回的updateCount也完全可能不等于2,这也是为什么大家一直建议写完数据库操作要校验返回结果的原因,别觉得这是多此一举。

会导致返回值不符合预期的常见情况

排除INSERT IGNORE的影响,以下场景都可能让拿到的返回值和预期的2对不上:

  • 语句带ON DUPLICATE KEY UPDATE逻辑:这是生产环境最常踩的坑。如果插入的数据碰到主键/唯一键冲突,MySQL会直接执行后面的更新逻辑,这时候受影响行数的统计规则和纯INSERT不一样:新插入成功一行返回1,冲突后更新了字段内容返回2,冲突后发现要更新的值和原值完全一样就返回0,最后加起来的总数完全可能偏离2。
  • 表上建了自定义触发器:如果目标表配了BEFORE INSERT/AFTER INSERT触发器,部分触发器逻辑要么会改变实际插入成功的行数,要么会干扰MySQL对受影响行数的统计,最终返回的数值就不准。
  • JDBC连接参数改了行数统计规则:MySQL的JDBC驱动有个useAffectedRows配置项,参数开关不同,行数统计逻辑完全不一样。默认配置下驱动返回的是「语句匹配到的行数」,不是「实际发生数据变更的行数」,碰到特殊场景返回值就和预期的插入数对不上。
  • 非事务引擎的部分写入问题:如果表用的是MyISAM这类不支持事务的存储引擎,多值插入过程中要是碰到字段超长、类型不匹配这类错误,已经执行完的前序插入不会回滚。要是碰到特定版本的驱动/服务端没有正常抛出异常,拿到的返回值就是实际插入成功的行数,大概率小于2。
  • 版本bug:不管是MySQL服务端还是JDBC驱动,部分历史版本都出过好多值插入场景下受影响行数统计错误的问题,极端场景下会返回完全不对的数值。
其他要注意的点

顺便提一句,贴出的示例代码本身有个低级笔误:打印日志的时候写的是System.out.println("update: " + update);,但实际存行数的变量叫updateCount,这段代码连编译都过不了,和运行时的返回值问题没关系。
另外要区分清楚:如果INSERT执行时直接抛了主键冲突、权限不足、表不存在这类异常,程序会直接进异常捕获分支,根本拿不到updateCount,这类情况不属于我们说的「返回值不等于2」的讨论范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:27:53