mysql锁(2)

上一篇文章:https://www.nasuiyile.cn/160.html

img

以下的锁都是innodb才有的

间隙锁(gap锁)

当使用范围查询的时候,会给满足组条件的内容进行加锁,比如:

update employee set name='123' where id>3 and id<7;
以上sql语句执行的时候,就会把3到7中间的内容进行加锁

锁定一个范围,不会阻塞其他的gap锁,但会阻插入间隙锁

间隙锁基于非唯一索引(包括主键),它锁定一段范围内的索引记录。间隙锁基于下面将会提到的Next-Key Locking 算法,请务必牢记:使用间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据。

记录锁

是锁住记录,锁住索引的记录,而不是真正的数据记录,顾名思义,记录锁就是为某行记录加锁,它封锁该行的索引记录

  • 所示非主键索引,会在索引记录上枷锁后,在去主键索引上加锁
  • 表上没有索引,会隐藏的主键索引上加上锁
  • 如果要锁的列没有索引,进行全表记录枷锁

临键锁(next-key)

Next-key可以理解为一种特殊的间隙锁,也可以理解为一种特殊的算法.通过临键锁可以解决幻读的问题.每个数据航上的非唯一索引列都会存在一把临键锁,当摸个失误持有该数据行的临键锁时,会锁住一段左开右闭的区间.需要强调的是innodb中行级锁时基于索引实现的,临键锁值与非唯一索引有关,在唯一索引列(包括主键)上不存在临键锁

临键锁是记录锁与间隙锁的组合,它包含的范围既包含索引记录,又包含索引区间

在根据非唯一索引对记录进行update/for update(间隙锁) /LOCK IN SHARE MODE(共享锁)时,innodb会获取该记录行的临键锁,并同时获取该记录行下一个区间的间隙锁

临键锁的主要目的是为了避免幻读,如果把事务的隔离界别设置为提交度,临键锁也会失效(只存在RR也就是已提交读这个隔离级别),但innodb只在一定程度上面避免了幻读,没有真正解决幻读

意向锁

表锁如何和行锁共存

举个例子事务A锁住表中的一行,事务b锁住了整个表

单马上就有一个问题,事务a既然锁住了一行,其他事务就不可能修改这一行.与事务b锁住了一整个表形成了冲突.所以没有意向锁的时候,行锁与表锁之间共存就会出现问题

有了意向锁之后前面例子中的事务A在申请行锁(写锁)之前,数据库会自动先给事务A申请的表的意向排它锁.当事务b去申请表的写锁时,就会失败,因为表上有意向排它锁知乎事务b申请表的写锁的时候会被阻塞.

意向所的作用是:

当一个事物在需要获取资源的锁定时,如果该资源已经被排它锁占用,则数据库会自动给该事物申请一个该表的意向锁.如果自己需要一个共享锁定,就申请一个意向共享锁,如果需要的是某行或者某些行的排它锁定,则申请一个意向排他锁.

意向所是表还是行锁

意向锁是表级别的锁,原因如下

当我们需要给一个加表锁的时候,我们需要根据意向锁判断表中有没有数据航被锁定,以确定是否能成功.如果意向锁是行锁,那么我们就得遍历表中所有数据来进行判断.如果意向锁是表锁,则我们直接判断一次就真的表中是否有数据被锁定了

冲突性

IX 意向排它锁,IS 意向共享锁,X 排它锁,S 共享锁

xIXSIS
X冲突冲突冲突冲突
IX冲突兼容冲突冲突
S冲突冲突兼容兼容
IS冲突兼容兼容兼容

意向插入锁

意向插入锁是一种通过insert插入之前操作设置的间隙锁定。此锁发出插入意图的信号,如果是多个事务未插入间隙中的相同位置,则无需等待插入到同一行所有间隙中的多个事务。

在多十五同时写入不同数据值同意所有间隙的时候,并不需要等待其他事务完成,不会发生锁等待

假设一个值记录索引包含4和7不同的事物分别插入6和6,每个事务都会产生一个加在4-7之间的意向插入锁,获取在插入行上的排它锁,但是不会被相互所住,因为数据行并不冲突。

插入意向锁不会组织任何锁,对插入的记录会持有一个记录锁

自增锁

自增锁是mysql一种特殊的锁,如果表中存在自增字段,mysql便会自动维护一个自增锁

他是一种特殊的表级别锁,专门正对事务插入自增类型的列。最简单的情况,如果事务正在往表中插入记录,所有其他食物的插入必须等待,一百年第一个事务插入的行,是连续主键值

Last modification:November 17, 2023
如果觉得我的文章对你有用,请随意赞赏