MySQL为何未释放不匹配WHERE条件行的锁?对官方文档存疑
MySQL中SELECT ... FOR UPDATE锁定不符合条件行的原因解析
核心问题解析
你遇到的现象并非文档描述错误,而是对文档适用场景的理解存在偏差,具体原因如下:
IN子句的执行逻辑:当使用
id IN (10,11)时,MySQL会将其拆解为两次独立的唯一索引精准查找(id=10和id=11)。对于每个通过唯一索引定位到的行,InnoDB会立即加排他锁(X锁),之后才会检查附加的age=19条件。锁释放规则的适用范围:官方文档中提到的“释放不符合结果集条件的行的锁”,仅适用于范围扫描或索引全扫描中被扫过但最终被过滤的行。而通过唯一索引精准匹配到的行(包括IN子句中的单个值),即使后续不满足其他WHERE条件,InnoDB也不会主动释放锁——因为这些行是被明确定位到的,锁会持有到事务提交或回滚。
测试场景的锁行为:事务1中,
id=11的行通过唯一索引被找到并加锁,后续检查age=19不满足时,仅会过滤掉该行不返回结果,但锁不会释放。因此事务2执行UPDATE操作时会被阻塞。
验证正确锁释放的场景
若将查询改为范围扫描形式:
SELECT * from test.Persion p where id > 9 and id < 12 and age=19 for UPDATE;
此时InnoDB会扫描id=10和id=11的行,对于id=11不满足age=19的情况,会释放该行的锁,事务2更新id=11就不会被阻塞,这才符合文档中描述的锁释放规则。
内容的提问来源于stack exchange,提问作者haoyu wang
相关产品推荐
相关产品推荐

