#
共享锁和排它锁是在互斥的角度上看待锁的。
- 共享锁是指一个线程加锁之后,其他线程还是可以继续加同类型的锁
- 排它锁是指一个线上加锁之后,其他线上就不能再加锁了
概念很接近写锁和读锁,因为读锁本身就是共享的,而写锁就是排它的。
相当于一个信号,告诉别人我要加锁了,所以意向锁并不是一个真正物理意义上的锁。
意向锁和共享锁、排它锁结合,就有了意向共享锁和意向排它锁。
- 意向共享锁:希望获得一个共享锁
- 意向排它锁:希望获得一个排它锁
意向锁的意向重点就是想要拿到这个锁,但是最终能否拿到这个锁,是不确定的。
在MySQL里,使用意向锁的场景是在增删改查的时候,对表结构定义加一个意向共享锁,防止在查询的时候有人修改表结构;在修改表结构的时候,加一个意向排它锁,这也就是修改表结构的时候直接阻塞掉所有增删改查语句的原因。使用意向锁可以提高数据库的并发性能避免死锁问题。
记录锁、间隙锁和临键锁是面试中最难理解的三个概念
记录锁是指锁住了特定的某一条记录的锁,例如SELECT * FROM your_tab WHERE id = 31 FOR UPDATE
,在使用了主键作为查询条件,并且是相等条件下,将只命中一条记录,这一条记录就会被加上记录锁。但是如果查询条件里没有命中任何记录,那么就不会使用记录锁,而是使用间隙锁。
如果使用唯一索引作为条件,比如user
表里有一个email
列是唯一索引,那么这条查询语句也是使用记录锁。类似,如果email='your_email'
这条记录不存在,那么会变成一个间隙锁。
SELECT * FROM your_tab WHERE email='your_email' FOR UPDATE
举个例子,如果数据库只有id为(1,4,7)的三条记录,也就是id=3这个条件没有命中任何数据,那么这条语句会在(1,4)这里加上间隙锁,所以,在生产环境里遇到了未命中索引的情况,对性能影响很大
MySQL里本身是加临键锁的,但是临键锁本身是由间隙锁和记录锁合并组成的,所以这里先用间隙锁描述