数据库死锁(Deadlock)」错误解决
2025-11-08
这是个「数据库死锁(Deadlock)」错误
弹窗里写着:SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction。
意思是:后台在往数据库(多半是 MySQL/InnoDB)插入 CreateSheetDetails 这条记录时,和另一条并发事务互相等待锁,形成闭环,数据库主动回滚了其中一方,于是前端报错。
会怎么触发
多人/多进程同时操作同一批数据:比如同时“复制模板/创建表单/保存明细”,互相锁住了相关行或索引。
外键/唯一键检查导致的锁冲突:
SubjectId/TemplateSheetId/CreatedSheetId/ProjectId等外键在校验父表时,恰好别的事务在更新/删除父表。长事务/大扫描:没有合适索引导致校验或查重走全表或范围锁,锁住的范围过大。
重复点击/并发重试:前端按钮点了多次,后端同时跑了多条插入。
统一加锁顺序不一致:两个事务访问表、行的顺序不同,最容易产生死锁。
你现在可以怎么处理(非开发同学)
点“确定”后重试一次(间隔 2–5 秒)。死锁通常是偶发的,重试就能成功。
避免连续快速点击同一按钮,或同时在多个窗口/多人对同一项目做相同操作。
若频繁出现:记录发生时间、操作步骤和项目编号,发给系统管理员/开发定位。
从源头修复(给开发/运维)
捕获并自动重试:对错误码
1213(或 SQLSTATE40001)做指数退避重试 3–5 次,这是处理并发写入的标准做法。统一加锁顺序:所有相关事务按相同顺序访问表/行(例如先父表再子表、先项目再明细),减少循环等待的机会。
缩短事务:只把必要语句放进事务;尽早提交,避免在事务内做耗时逻辑/网络调用。
补齐和优化索引:
为外键列(如
SubjectId/TemplateSheetId/CreatedSheetId/ProjectId)建索引,降低外键校验锁范围。为参与唯一/查重的字段(如
UUID/UNIQUEID)确认存在高选择性的索引。降低隔离级别(仅在可接受的一致性前提下):从
REPEATABLE-READ调整为READ COMMITTED,减少 Next-Key/GAP 锁带来的冲突。避免大范围扫描:改写校验/查重语句,使用等值匹配;必要时把写入拆批。
排查死锁链:在故障发生后立刻抓取
SHOW ENGINE INNODB STATUS\G(最新死锁栈)INFORMATION_SCHEMA.INNODB_TRX/INNODB_LOCKS/INNODB_LOCK_WAITS或sys.innodb_lock_waits
看看涉及的两条语句、锁的对象和索引,针对性调整。幂等设计:如果是“复制/创建”类操作,加入业务幂等键(如
UNIQUEID),并使用INSERT … ON DUPLICATE KEY UPDATE或先查再插,配合重试更安全。
小结
这不是 Excel 本身的问题,而是后台数据库在高并发下插入时发生的死锁。
短期:重试即可;长期:加重试、统一锁序、补索引、缩短事务,并用死锁日志定位具体冲突点。

发表评论: