MySQL 锁 行锁(next-key,间隙锁gap lock,记录锁 record lock) 表锁 页锁

MySQL 锁

事务级别与脏读幻读

在这里插入图片描述

s锁和x锁

共享锁(s锁,share lock,读锁):一个事务lock in share mode,其他事务读数据不能更新数据,只能加s锁进行读数据,阻塞其它事务修改真实数据。

排他锁(x锁,exclusive lock,写锁):一个事务for update 加上x锁,其他事务不能对相关数据进行加其他锁。update,insert,delete默认会加上排他锁。

意向锁(Itention Locks)

表示当前表中有记录已被上锁。

比如某行数据被加了s锁,则这张表上就会增加一个IS的意向锁标值。同理x锁。

该锁能够快速判断该表已经有记录上锁了,避免遍历来查看锁,提高加锁效率。

行锁、表锁和页面锁

MyISAM和MEMORY储存引擎采用表级锁

BDB储存引擎采用页面锁

InnoDB既支持行级锁也支持表级锁,默认采用行级锁

表锁:开销小,加锁快,不会出现死锁,锁定粒度大,发生锁冲突概率大,并发度低。

行锁:开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突概率小,并发度高。

页面锁:性能介于行锁表锁之间,会出现死锁

对一个表大量使用行锁,是会升级为表锁的

行锁是通过给索引上的索引项加锁来实现的,通过索引条件使用行锁,否则使用表锁

InnoDB select默认不加任何锁。手动指定lock in share mode 共享锁、for update 排他锁

什么情况下使用什么锁?

当使用update、insert、delete、select… for update时,有指定的索引列,则使用行锁;

如果没有指定索引,则InnoDB使用表锁。

for update排他锁没有线程对该结果集中的任何行数据使用排他锁或共享锁,否则申请会阻塞select * from account where id > 8 and id <> 10 for update;(会对查询结果集中每行数据都添加排他锁)

next-key、记录锁、间隙锁

间隙锁和next-key锁都是RR隔离级别特有的

Next-key锁:必须在RR隔离级别下,行锁默认使用next-key锁。锁记录本身,同时还要锁记录之间的间隙,例如select * from student where id > 3 and id<=5 for update 会锁住区间(3,5],(5,~) 的数据。【锁住的区间会包含最后一个record的右边的临键区间】

当该查询没匹配到任何记录的时候退化为间隙锁

间隙锁(Gap Lock):必须在RR隔离级别下,行锁默认next-key锁,当使用索引查询没有查到任何记录的时候退化为间隙锁。假设目前仅存在id=1和id=4。select * from student where id = 3 for update,select * from student where id > 1and id < 4 for update,会锁住(1,4)区间的值。

记录锁(Record Lock):mysql默认的行锁是next-key锁。当使用唯一性索引等值查询匹配到记录时,退化为记录锁。


next-key:包含了间隙锁和记录锁。

InnoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引检索数据的时候InnoDB才使用行锁,否则只能用表锁。

间隙锁的目的

  1. 防止幻读、防止间隙内有新数据插入
  2. 防止已存在的数据更新为间隙内的数据。

如果看到这里了,强烈推荐看看这篇博客:Mysql加锁过程详解(9)-innodb下的记录锁,间隙锁,next-key锁
超级详细的间隙锁案例,值得学习。

参考资料:

  1. 面试专栏 72期 MySQL是如何实现ACID的
  2. Mysql X锁,S锁、间隙锁、死锁
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值