批量导入用 savepoint 做单条回滚,失败的 200 条都 rollback to savepoint 了,但后续批次一直报 1205,data_locks 里锁数量只增不减。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,回滚到保存点只撤销数据改动,事务本身还开着,之前拿到的锁要等整个事务结束才释放。每次回滚都留下一点锁,攒到后面就把相关行全占住。
「savepoint 锁释放」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。别只看报错的最后一行,往上看几行,真正的起因通常在上面。
SELECT trx_id, trx_rows_locked FROM information_schema.innodb_trx; SHOW ENGINE INNODB STATUS\G
同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
具体做法是,确认 savepoint 外层事务有没有在批次结束时提交;把每批做成独立事务 失败整批回滚更干净;必须用 savepoint 时 控制单个事务里的批次数;用 trx_rows_locked 观察单个事务的持锁数量。
最后用这个标准收尾,导入过程中单个事务的持锁行数保持在批次大小以内 1205 不再出现。
