Spring Boot中NamedParameterJdbcTemplate返回受影响行数异常
问题排查与解决方案
核心现象
DAO方法执行UPDATE feed SET trash = TRUE WHERE id = :id时,重复传入同一feedId始终返回受影响行数1;但在MySQL Workbench中执行替换参数后的相同SQL,返回受影响行数0,且两者连接同一数据库。
排查方向与解决方法
1. 事务提交状态不一致
应用可能开启了事务但未及时提交,导致Workbench无法读取到更新结果:
- 检查方法是否被
@Transactional修饰,若无需事务可直接移除该注解; - 若需要事务,确保方法执行后事务正常提交(比如调整事务传播行为,或在测试场景中手动触发提交)。
2. SQL统计逻辑差异(最常见原因)
MySQL默认返回实际被修改的行数,而Spring的NamedParameterJdbcTemplate可能返回匹配到的行数(即使字段值未发生变化):
- 验证方式:在Workbench中执行以下指令:
-- 查看默认返回行数 UPDATE feed SET trash = TRUE WHERE id = 你的feedId值; SELECT ROW_COUNT(); -- 此时返回0,因为trash已经是TRUE -- 切换到OLD模式,返回匹配行数 SET sql_mode = 'OLD'; UPDATE feed SET trash = TRUE WHERE id = 你的feedId值; SELECT ROW_COUNT(); -- 此时返回1 - 解决方案:
- 若希望应用与Workbench返回结果一致,可在JDBC连接URL中添加
useAffectedRows=true,让应用返回实际修改行数; - 若需保持现有应用逻辑,可在Workbench中临时设置
SET sql_mode = 'OLD'或修改MySQL全局配置文件,统一统计逻辑。
- 若希望应用与Workbench返回结果一致,可在JDBC连接URL中添加
3. 参数或数据类型不匹配
确认Workbench中使用的id值与应用传入的feedId完全一致:
- 核对应用日志中的参数值(可通过开启Spring SQL日志:
logging.level.org.springframework.jdbc=DEBUG查看实际执行的SQL和参数); - 检查表结构中
id字段的数据类型(如bigint)与应用传入的long类型是否匹配,避免类型转换导致的匹配失败。
4. 会话变量差异
应用与Workbench的数据库会话可能存在不同的变量设置(如字符集、时区),导致id匹配异常:
- 在Workbench和应用中分别执行
SHOW VARIABLES LIKE '%sql_mode%';、SHOW VARIABLES LIKE '%character_set%';,对比变量值是否一致,必要时统一配置。
内容的提问来源于stack exchange,提问作者Harsh Kanakhara
相关产品推荐
相关产品推荐

