(面试题)MySQL中锁的类型有哪些?

32 阅读2分钟

从读写角度上来看:

  • 共享锁(Share Lock):其实就是我们说的读锁。如果加上这个锁,我们可以读这个数据,其他事务可以同时加读锁,但是不能加写锁。
我们平时加读锁的语句就是,select后面加上lock in share mode
  • 排他锁(Exclusive Lock):其实就是我们说的写锁。如果加上这个锁,我可以对数据进行读取或修改,其他事务不能对该数据加读锁或写锁。
我们平时加读锁的语句就是,select后面加上for update

扩展:我认为这是一种很好的思想,我们JUC并发包,就很好地借鉴了这一思想,比如说我看过CopyOnWriteList源码,它里面就是用这样地方式增加读写并发度的


从粒度层面来看:

  • 表锁,就是锁住整张表,一般在不加索引或者索引失效的时候锁住整张表。一般要避免表锁,会降低并发度。
    比如给姓名不加张三的人加锁,这时候索引失效,加的就是表锁
  • 行锁,就是锁一行或者多行,需要注意的是加在索引上的
    比如给姓名叫张三的人加锁,这是后可能锁住多个叫张三的记录,锁住一行或多行
  • 间隙锁,就是锁住某个区间。锁的是区间,不单单是记录
    比如给年龄在[1,10]区间的人加锁,锁的是区间。原有数据1-10无法修改,并且新的数据也不能插入1-10区间
  • 临建锁,相当于是记录锁 + 间隙锁,又叫next-key lock。这个用途主要是RR级别下避免幻读,这是一个左开右闭的锁

从锁的意向来看:

这里模拟一个场景,事务A对表中的记录加了一个排他锁,然后事务B这时候需要对这个表加一个排他锁,事务B就需要扫描整张表,查看是否有其他事务对这张表中记录加了排他锁。

但是实际可能没有那么麻烦,事务A对表中加了一个排他锁,同时对表也加了一个意向排他锁。然后事务B一看这个表有意向排他锁,事务B就直接等待事务A执行完后再加表锁。

  • 意向排他锁,当一个事务试图对整个表加排他锁之前,首先需要获得这个表的意向排他锁
  • 意向共享锁,当一个事务试图对整张表加共享锁之前,首先需要获得这个表的意向共享锁