首页 > 其他分享 >锁的分类(四)

锁的分类(四)

时间:2022-10-01 10:39:10浏览次数:39  
标签:记录 分类 开启 id 插入 student 连接

  • ​页级别:记录锁​
记录锁也就是仅仅把一条记录锁上,官方的类型名称为: LOCK_REC_NOT_GAP 。比如我们把id值为8的那条记录加一个记录锁的示意图如图所示。
仅仅是锁住了id值为8的记录,对周围的数据没有影响。

锁的分类(四)_死锁

  • 结论
记录锁是有S锁和X锁之分的,称之为 S型记录锁 和 X型记录锁 。
当一个事务获取了一条记录的S型记录锁后,其他事务也可以继续获取该记录的S型记录锁,但不可以继续获取X型记录锁;
当一个事务获取了一条记录的X型记录锁后,其他事务既不可以继续获取该记录的S型记录锁,也不可以继续获取X型记录锁
  • 案例
# 案例1
# 开启第1个连接
# 开启1个事务
begin;
# 相当于为这1行开启1个排他锁
update student set name = "chen" where id = 1;

# 开启第2个连接
# 开启第2个事务
begin;
# 对其他行开启共享锁,开启成功
select * from student where id = 3 lock in share mode;
# 对第1个连接中的那一行开启共享锁,开启失败,因为不兼容
select * from student where id = 1 lock in share mode;

# 对其他行开启排他锁,开启成功
update student set name = "li" where id = 3;

# 对同一行开启排他锁,开启失败
update student set name = "xing" where id = 1;

# 当第1个连接中释放排他锁,关闭事务后
commit;

# 第2个连接中对这1行开启排他锁,开启成功
update student set name = "xing" where id = 1;
  • ​页级锁:间隙锁(Gap Locks)​​:指定2行中间不允许插入数据
MySQL 在 REPEATABLE READ 隔离级别下是可以解决幻读问题的,解决方案有两种,可以使用 MVCC 方案解决,也可以采用 加锁 方案解决。但是在使用加锁方案解决时有个大问题,
就是事务在第一次执行读取操作时,那些幻影记录尚不存在,我们无法给这些 幻影记录 加上 记录锁 。InnoDB提出了一种称之为Gap Locks 的锁,官方的类型名称为: LOCK_GAP

锁的分类(四)_MySQL_02

  • 案例
# 案例1
# 开启1个新的连接,开启1个事务
begin;
# 为某个不存在的行添加1个共享锁
select * from student where id= 5 lock in share mode;

# 开启第2个新的连接,开启1个事务
begin;
# 为同一行添加1个排他锁,按道理说不能添加成功,针对同一行记录添加共享锁和排他锁是不兼容的
# 但如果这一行记录是不存在的,则可以同时添加共享锁和排他锁
# 这一行不存在的记录存在与某2行记录的中间,这时添加的这个锁也成为间隙锁
# 添加1个排他锁,添加成功
select * from student where id = 5 for update;

# 在间隙锁还未释放之前,向这个间隙插入数据,会插入失败,会处于阻塞状态,这就是间隙锁的作用
insert into student(id, name, class) value(6, "gou", "man");

# 案例2
# 开启1个新的连接,开启1个事务
begin;
# 由于最大的数是20,如果在20到无穷大的这个区间开启1个间隙锁,则20到无穷大这个区间将被间隙锁锁定,不允许插入数据
select * from student where id = 25 lock in share mode;

# 开启第2个连接,开启1个事务
begin;
# 向20到无穷大的区间插入数据,插入失败
insert into student(id, name, class) value(21, "gou", "man");
insert into student(id, name, class) value(26, "gou", "man");

# 向20之前的区间插入数据,插入成功
insert into student(id, name, class) value(17, "gou", "man");
  • ​间隙锁导致死锁​
# 开启第1个新的连接,开启1个事务
begin;
# 开启1个间隙锁
select * from student where id = 5 lock in share mode;

# 开启第2个连接,开启1个新的事务
begin;
# 开启1个相同的间隙锁
select * from student where id = 5 for update;

# 第2个连接中向间隙中插入1条记录,会处于阻塞状态
insert into student(id, name, class) value(7, "aaa", "giao");

# 切换到第1个连接的页面,向间隙中再次插入1条记录,这时会直接报死锁的错误
insert into student(id, name, class) value(6, "bbb", "giao");

# 死锁的原因:第1个间隙锁不允许第2个连接中的插入操作执行,第2个间隙锁不允许第1个连接中的插入操作执行
# 要想第1个连接中的插入操作执行,第2个连接释放锁,但第2个连接中有1条插入语句处于阻塞状态,不能结束
# 要想第2个连接中的插入操作执行,第1个连接释放锁,但第1个连接中有1条插入语句处于阻塞状态,不能结束
# 最后第1个连接中的插入语句报死锁错误,第2个连接中的插入语句则插入成功了

# 第2个连接中插入语句执行成功的原因:发生死锁时,mysql的处理死锁的1中策略是将某1个处于僵持状态的事务进行回滚,选择成本更低的1个事务执行
# 因此这里回滚了第1个连接中的事务,第2个连接没有阻塞则执行成功了



标签:记录,分类,开启,id,插入,student,连接
From: https://blog.51cto.com/chniny/5728128

相关文章

  • 锁的分类(六)
    ​​页级锁​​页锁就是在页的粒度上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有多个行记录。当我们使用页锁的时候,会出现数据浪费的现象,但这样的浪费最多也就是一......
  • 锁的分类(五)
    ​​临键锁(Next-KeyLocks)​​有时候我们既想锁住某条记录,又想阻止其他事务在该记录前边的间隙插入新记录,所以InnoDB就提出了一种称之为Next-KeyLocks的锁,官方的类......
  • 锁的分类(七)
    ​​显式锁​​#通过特定的语句进行加锁,我们一般称之为显示加锁#显式共享锁select...lockinsharemode#显式排他锁select...forupdate​​隐式锁​​隐式锁是在......
  • 锁的分类(八)
    ​​全局锁​​全局锁就是对整个数据库实例加锁。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据......
  • ALV :汇总,分类汇总(小计),排序,过滤
    货铺QQ群号:834508274下面开始干货部分……ALV标准功能汇总,分类汇总,排序,过滤这些功能除了可以直接使用它的标准功能按钮之外,你也可以在程序里设定,让ALV列表第一次显示出来就......
  • 朴素贝叶斯分类器
    朴素贝叶斯分类器朴素贝叶斯算法:它是一种基于贝叶斯定理的监督机器学习算法。它是一种用于各种分类任务的概率机器学习算法。在我们深入探讨这个话题之前,我们首先要了解......
  • SARscape5.6.2形变结果分类工具介绍
    SARscape5.6.2版本干涉叠加模块新增时序分类工具,可对时序InSAR进行高级后处理和分析。该工具通过现象特征和参数分析对位移时间序列进行自动分类。可使用外部气象数据(雨、......
  • 网络编程-IP地址的分类
    网络编程-IP地址的分类网络中有多台计算机,它们必须通过某种标识来区分每一台机器,这个用于区分的标识这就是IP地址;IP地址由4个数字组成,形如“192.168.1.1”。(其实是4个字......
  • 18个面向初学者的经典开源计算机视觉项目-图像分类篇Inception(三)
    在研究这篇文章时,有一点很清楚。2014年是发展真正流行的图像分类预训练模型的标志性一年。尽管上述VGG-16在当年的ILSVRC中排名第二,但排名第一的不是别人,正是谷歌——通过它......
  • 深度学习:文本分类模型中的“蒸”功夫
    作者:Xingzhe.AI来自:行者AI 前言2018年Bert的横空出世给自然语言处理带来了巨大的突破,Bert及其衍生模型在多个文本处理下游任务中达到了SOTA的结果。但是这样的提升是......