CREATE DATABASE IF NOT EXISTS testdb; use testdb; -- 注意:必须为条件列建立非唯一索引,否则锁全表,下文会验证 CREATE TABLE students_nk_lock ( id INT PRIMARY KEY, name VARCHAR(50), score INT, key idx_score(score) ); INSERT INTO students_nk_lock (id, name, score) VALUES (1, 'Alice', 85), (4, 'Bob', 90), (7, 'Carol', 95), (10, 'Lucy', 100);
版本 5.7 ,默认 RR 级别。
BEGIN; SELECT * FROM students_nk_lock WHERE score >= 90 FOR UPDATE;
BEGIN; INSERT INTO students_nk_lock VALUES(0, 'Dave', 83); -- 阻塞 INSERT INTO students_nk_lock VALUES(2, 'Dave', 84); -- 阻塞 UPDATE students_nk_lock SET score=85 WHERE score=85; -- 阻塞 INSERT INTO students_nk_lock VALUES(5, 'Dave', 85); -- 阻塞 INSERT INTO students_nk_lock VALUES(5, 'Dave', 91); -- 阻塞 INSERT INTO students_nk_lock VALUES(11, 'Dave', 101); -- 阻塞
对于普通索引,按个人理解应该是锁住 ({1, 85} -> +inf)
这段索引记录范围,然而实测貌似锁了全表,甚是不解!来请教相关大佬
![]() | 1 wenxueywx 2024-05-31 16:47:27 +08:00 SELECT * FROM students_nk_lock WHERE score >= 90 FOR UPDATE; |
![]() | 2 wenxueywx 2024-05-31 16:47:56 +08:00 ![]() 查询走的全表扫描吧 你 explain 看看 |