导入 5 万条客户,校验全部通过,入库时把 300 条已经被客服改过的手机号覆盖回文件里的旧值,事后对账发现 300 条回退。日志里能对上时间点,这种反而好排。
校验和入库隔了几十秒,中间没有锁也没有版本比对,校验结果被当成最终值。更新语句按主键直接覆盖,不判断记录是否已经变化。这一点先确认清楚,后面就不用反复试。
UPDATE customer SET phone = ?, version = version + 1 WHERE id = ? AND version = ?;
这次卡住的地方就在「导入校验入库分离」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。
日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
处理上按这个顺序:入库带 version 或 updated_at 条件 版本不一致就记为冲突;缩短校验到入库的间隔 或者边校验边入库;冲突记录单独输出 让人工确认保留哪一份。
结果对不对很好判断,再次导入时 300 条冲突全部被拦下并写进冲突清单,已修改的手机号没有被覆盖。
