锁住了某一段记录的锁,直观的说就是锁住了一个范围的记录,比如在查询的时候使用了< <= BETWEEN 之类的范围查询条件,就会使用间隙锁
SELECT * FROM your_tab WHERE id BETWEEN 50 AND 100 FOR UPDATE
间隙锁会锁住(50,100)之间的数据,而50和100本身会被记录锁锁住,类似的<=这种查询,也可以认为=的那个值会被记录锁锁住。
如果表里没有50,数据库会一直向左,找到第一个存在的数据,比如40;同理,如果表里没有100,那么数据库就会一直向右,找到第一个存在的数据,比如120。此时,如果有人想要插入一个主键为70的行,是无法插入的,需要等到这个SELECT语句释放掉间隙锁。
间隙锁我们一般说两边都是开的,即端点是没有被间隙锁锁住的。记录锁和记录锁是排它的,但是间隙锁和间隙锁不是排它的,也就是说两个间隙锁之间即使重叠了,也还是可以加锁成功的
临键锁是一种很独特的锁,直观上可以看作是一个记录锁和间隙锁的组合,也就是说临键锁不仅仅是会用记录锁锁住命中的记录,也会用间隙锁锁住记录之间的空隙。
临键锁和数据库隔离级别的联系最为紧密,可以解决在可重复读隔离级别之下的幻读问题。
间隙锁是左开右开,临键锁是左开右闭 ,如果id只有(1,4,7)三条记录,那么临键锁就把(1,4]锁住。
(幻读就是同一事务里面,同一个sql查询查出来的记录行数不一样。为什么会不一样?因为有别的事务在你执行sql的时候进行了插入,插入到了你的查询条件范围内了,导致你上一次查还好好的,下一次查就莫名奇妙多出来记录了)