05 请分析RR可能导致锁范围扩大的原因和解决思路

vvEcho 2025-03-07 10:50:46
Categories: > Tags:

假设查询涉及SELECT … FOR UPDATE锁,请分析在RR(可重复读)隔离级别下可能导致的锁范围扩大问题。如何通过索引设计避免锁全表?请结合SELECT * FROM commission WHERE merchant_id=? AND month=’2025-02’ FOR UPDATE示例说明

mysql的InnoDB在RC级别下会把不匹配的行的行锁提前释放,在RR和serializable隔离级别下,仍然会持有行锁直到事务提交。

所以在给出的sql中,如果没有命中索引,那么就会走全表扫描;会锁定扫描到的所有行,造成锁范围扩大的问题

解决方式是,给merchant_id 加上索引,但是考虑到merchant_id的区分度,可以给merchat_id和month建立联合索引;避免只有merchat_id一个索引情况下,行锁和间隙锁的产生;

另外结合项目,如果是分库分表的话,例如按merchat_id的hash分片,需要将merchat_id做为索引的第一列;可以用SHOW ENGINE INNODB STATUS分析锁冲突,尤其关注Gap Lock竞争