意向锁,协调行锁和表锁之间的关系的,实现了“表锁是否冲突”的快速判断。协调表的读写锁和行的读写锁(不同粒度锁)之间关系。 场景:获取行的S锁,需要先获取表的IS锁;获取行的X锁,需要先获取表的IX锁。 注:与意向锁冲突的不是行的X锁,是表的X锁! IX 与表的 X 和 S 冲突,意思当前表有行锁X锁,不能上表的X或S锁。 IS 与表的 X 冲突,意思当前表有行锁S锁,不能上表的X锁。 why意向锁:“表锁是否冲突”的快速判断。否则需要遍历表去判断行锁的存在,才能判断冲突。
聚簇索引 索引命中:对这个 id 聚簇索引加 X 锁 索引未命中:对 id 这个聚簇索引加 GAP 锁,GAP的范围是两个索引的间隙 范围条件: 对范围区间内命中的id聚簇索引加Next-Key 锁,即左开右闭的GAP锁+X锁。eg: UPDATE student SET age = 100 WHERE id < 3
在没有索引的时候,只能走聚簇索引,对表中的记录进行全表扫描。会给所有记录加行锁,所有聚簇索引和聚簇索引之间还会加上 GAP 锁。 eg: UPDATE student SET age = 100 WHERE age = 33; age无索引。 why: RR 下要保证当前读时不出现幻读。需要锁全表!否则任何一个记录都可以变成age=33, 任何一个地方都可以insert一条age=33。再执行该sql的时候会发现多出记录了。
session1 : update student set age = 88 where stu_no = 1; session2 : update student set age = 99 where stu_no = 3; session1 : update student set age = 99 where stu_no = 3; session2 : update student set age = 88 where stu_no = 1;
死锁, 一个有stu_no=1的 X RECORD锁,一个有stu_no=3的。
两个gap锁各自阻塞另一个事务的插入意向锁 stu_no字段 是唯一索引_
1 2 3 4
session1 : delete from student where stu_no = 8; session2 : delete from student where stu_no= 7; session1 : insert student (stu_no) values (6); session2 : insert student (stu_no) values (9);