MySQL InnoDB支持三种锁:
- 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key。
- 间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙不变。间隙锁是针对事务隔离级别为可重复读或以上级别而设计的。
- 后码锁(Next-Key Lock):行锁和间隙锁组合起来就叫Next-Key Lock。
默认情况下,InnoDB工作在可重复读隔离级别下,并且会以Next-Key Lock的方式对索引行进行加锁,这样可以有效防止幻读的发生。Next-Key Lock是行锁和间隙锁的组合,当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录。
行锁(Record Lock)
当需要对表中的某条数据进行写操作(insert、update、delete、select for update)时,需要先获取记录的排他锁(X锁),这个就称为行锁。
针对InnoDB RR隔离级别,行锁是基于表索引的,如果where条件中的字段是非索引列,将产生不一样的现象:没有索引将产生表锁,导致整张表的写操作都会出现等待。
这是一个索引记录锁,它是建立在索引记录上的锁(主键和唯一索引都算),很多时候,锁定一条或多条数据。由于无索引,往往会导致整个表被锁住,建立合适的索引可以防止扫描整个表。
Gap锁(Gap Lock)
在MySQL中select称为快照读,不需要锁,而insert、update、delete、select for update则称为当前读,需要给数据加锁,幻读中的“读”即是针对当前读。
MySQL默认事务隔离级别是可重复读,这个隔离级别为了避免幻读现象,引入了这个间隙锁,对索引项之间的间隙上锁。
当我们查询的记录不存在,没有命中任何一行记录,无论用等值查询还是范围查询,它使用的都是间隙锁(Gap Lock)。RR隔离级别才有gap lock,Read Commited下没有。
后码锁(Next-key Locks)
后码锁是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间。
注:Next-key Lock的主要目的,也是为了避免幻读(Phantom Read)。如果把事务的隔离级别降级为RC,Next-key Lock则也会失效。
当我们使用了范围查询,不仅命中了记录,还包含了间隙,在这种情况下我们使用的就是Next-key Lock,它是MYSQL里面默认的行锁算法,相当于记录锁加上间隙锁。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/116471.html