innodb_lock_wait_timeout不控制事务优先级,仅设定行锁等待超时时间;InnoDB无抢占机制,锁分配按请求顺序(FIFO),CATS调度器虽自适应优化唤醒逻辑但不可配置,真正影响锁获取的是事务发起时间、索引命中情况及死锁时undo量大小。

innodb_lock_wait_timeout 根本不控制事务优先级
它只决定一个事务在等待行锁时最多忍多久,超时就报 Lock wait timeout exceeded 错误。MySQL InnoDB 没有“高优先级事务插队”机制,锁分配严格按请求顺序(FIFO),直到 8.0.3 引入 CATS 算法——但 CATS 也不接受人工干预,它是自动感知争用并动态调整调度策略的底层机制,**无法通过配置项开启、关闭或调权**。
MySQL 8.0 的 CATS 调度器不能被配置或绕过
CATS(Contention-Aware Transaction Scheduling)在 8.0.3+ 默认启用,它让高争用热点行上的事务排队更“聪明”,比如避免多个事务反复争同一行导致的无效唤醒。但它:
- 不暴露任何用户可控参数,
innodb_lock_wait_timeout对它完全无影响 - 不改变“先到先得”的基本规则,只是优化了等待队列的唤醒逻辑
- 不会因为某个事务用了
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ就给它更高权重
想靠改参数让订单扣减事务“压过”报表查询?做不到。CATS 不提供这种能力。
真正能影响谁先拿到锁的,只有这三件事
锁获取顺序由以下因素实际决定,和 innodb_lock_wait_timeout 无关:
- 事务发起时间:早提交的事务自然早释放锁,后续事务才能获取;晚发起的只能等
-
是否命中索引:
UPDATE t SET x=1 WHERE id=100只锁一行;WHERE status='pending'没索引 → 锁全表或大量间隙 → 阻塞面扩大 -
死锁检测结果:发生死锁时,InnoDB 回滚
undo_log更小的那个事务(即修改行数更少的),这不是优先级,是代价最小化选择
所以你看到两个事务卡住,其中一个突然报错 Deadlock found when trying to get lock,不是它“优先级低”,而是它刚做的更新比对方少。
该调 innodb_lock_wait_timeout 的唯一合理场景
只在确认存在**可控的、短暂的行级争用**时微调它,例如:
- 高频更新单行计数器(如库存扣减),已加唯一索引且事务极短 → 可设为
3~5 - 业务侧明确知道某类操作平均耗时 8 秒,且允许最多等一倍时间 → 设为
15 - 绝对不要设成
300或更大:它不会帮你“抢到锁”,只会让阻塞持续更久,拖垮连接池
调完必须同步检查 Innodb_row_lock_time_avg 和 Innodb_row_lock_waits,如果平均等待时间远高于你设的 timeout 值,说明问题不在超时设置,而在事务没及时提交或 SQL 没走索引——这时调参毫无意义。











