MySQL锁的种类

共享锁与排他锁

其实MYSQL中,锁可以分为两大类

  • S锁(共享锁)
  • X锁(排他锁)

SS不互斥,X与任何锁都互斥

SELECT … LOCK IN SHARE MODE 这种读取需要对记录上S锁
SELECT … FOR UPDATE 这种读取需要对记录上X锁

一般情况下,为了高性能和高并发需求,我们不会使用表锁。
平日里UPDATE和SELECT要用也是用行锁。

表锁一般会用在DDL语句上,比如ALTER TABLE时,应该锁定整个表,这个时候,元数据锁就出现了

元数据锁(MDL)

元数据锁也分为读锁和写锁
当一个事务需要读取表中的元数据时,会获取读锁
但是当一个事务要修改元数据时,会获取写锁

但是业务中用到表锁,肯定会与行锁产生冲突。InnoDB加表锁时,怎么判断表中是否有行锁呢?

意向锁

于是意向锁诞生了

  • IS 共享意向锁
  • IX 排他意向锁

这两个锁是表级别的锁,当需要对表中某条数据上S锁时,先在表上加一个IS锁,表明此时表中有S锁。
X锁也会在表上加上一个IX锁,表明此时表中有X锁。

这样操作之后,如果要加表锁,直接看看表上面有没有IS或者IX锁。

因此IS和IX的作用就是在上表级锁时,可以快速判断是否可以上锁,不需要遍历表中所有的记录
而他的作用也只仅仅是打个标记而已。

行锁

主要有以下三种

  • 记录锁
  • 间隙锁
  • 临键锁

记录锁

顾名思义,是锁住当前记录,作用在索引上的。所以记录锁总是会锁住索引上的记录

间隙锁和临键锁

间隙锁会锁住索引上的间隙,防止其他事务在这个间隙中插入新的记录。
间隙锁不会冲突,因为间隙锁的唯一目的就是防止其他事物插数据到间隙中。所以存在多个间隙锁锁住相同的间隙。

临键锁是记录锁和间隙锁的结合,会锁住索引上的记录和间隙。
临键锁是间隙锁和记录锁的结合,会锁定一个前开后闭的区间。

插入意向锁

插入意向锁是和间隙相关的锁,但是他不是锁定某个间隙,而是等待某个间隙。
比如有一个事务被间隙锁阻塞,这个事务会生成一个插入意向锁,表明等待这个间隙锁释放。