likes
comments
collection
share

MySQL InnoDB 锁的基本类型

作者站长头像
站长
· 阅读数 16

共享锁

共享锁(Shared Lock) 是一个行级别的锁,当一个事务获取了一行数据的共享锁以后,就可以读取数据内容,所以它也称之为读锁。而且多个事务可以共享一把读锁

可以用 select * from table(表) lock in share mode;的方式手动给数据加上一把读锁。

而锁释放的时机是什么时候呢?

答案是:只要事务结束的时候,锁就会自动释放,包括提交事务和结束事务。

这里需要注意的是必须使用到索引才会建立共享锁,因为行锁是Innodb通过给索引上的索引项加锁实现的,若是没有命中索引,那么就没机会加行锁,若是需要锁,则会直接加表锁。

排他锁

排它锁(Exclusive Locks),是用来加锁然后进行操作数据的,所以又叫做写锁。只要一个事务获取了一行数据的排它锁,其他的事务就获取不到这一行数据的共享锁排它锁。也就是说无法对这行数据进行读写,等到拿到锁的事务将锁释放之后才能进行读写。

排它锁的加锁方式有两种:

  1. 自动加排他锁,当我们在操作数据的时候,也就是执行增删改操作的时候,都会默认加上一个排它锁。

  2. 手工加锁,我们可以使用FOR UPDATE 给一行数据加上一个排它锁,这个比较常用。

select * from table where id = 1 for update;

释放锁也是等待事务完成就会自动释放。

意向锁

首先意向锁是由数据库自己维护的

也就是说,当我们想给一行数据加上共享锁的时候,数据库会自动在这行数据的表上面加一个意向共享锁

当我们给一行数据加上排他锁之前,会自动在这张表上面加一个意向排他锁

如果一张表上面至少有一个意向共享锁,说明已经有其他的事务给其中的某些数据行加了共享锁。

这样做的目的是当有事务来进行加锁的时候,可以优先进行一次判断。不用等已经找到了索引,才看到已经有锁了。

记录锁

当我们对于唯一性的索引(包括唯一索引和主键索引)进行等值查询的时候,就会精准匹配到一条记录,这个时候使用的就是记录锁。

比如 当使用where id = 1;的时候,查询到了值,就使用的是记录锁。

间隙锁

若是我们查询的记录不存在,无论使用的是等值查询还是范围查询,它使用的都是间隙锁。

锁定一个范围,但不包含数据本身 而引入间隙锁的初衷,是为了解决幻读现象

临键锁

当 SQL 执行按照非唯一索引进行数据的检索使用范围查询时,会给匹配到的行上加上临键锁,是记录锁与间隙锁的组合。

他是左开右闭区间,它锁定的范围遵循:最后一个记录的下一个左开右闭区间。

当索引范围是(-∞,5](5,10](10,15](15,20](20,25](25,+∞]

Update userinfo SET age=19 where id= 10;

则会锁定(5,10),(10,15)这两个区间。也就是说,InnoDB将获得该记录行的临键锁,并同时获得该记录行下一区间的间隙锁

这里,InnoDB 锁的基本类型就说完了,之后我也会对每个锁的原理进行深入的研究。