【Mysql高级】【第十五章】【锁】

1.概述

事务的隔离性由锁来实现

在这里插入图片描述

2.Mysql并发实务访问相同记录

并发事务访问相同记录的情况大致可以划分为3种:

2.1 读-读

在这里插入图片描述

2.2 写-写

在这里插入图片描述
在这里插入图片描述
锁结构和事务是一一对应的,有几个事务,就会生成几个锁结构,如果该记录还有别的事务要进行操作,会对别的事务也建立锁结构!

锁的生成
在这里插入图片描述

事务T1 提交之前
在这里插入图片描述

事务t1 提交之后
在这里插入图片描述

小结
在这里插入图片描述

2.3 读-写或者写-读

在这里插入图片描述

2.4 并发问题的解决方案

(1)读MVCC ,写加锁

在这里插入图片描述

(2)读和写都加锁

  • 场景:读取的数据必须是最新数据
    在这里插入图片描述
  • 脏读问题:B事务先对记录x进行修改,然后A事务去读取记录x,只要B还没提交,A就不能读取记录x;A读不到B未提交的数据
  • 不可重复读:A事务先读取读记录x,然后B事务想要对x进行修改,此时B就必须等待A事务结束,才能写;
  • 幻读:事务A读取了一个范围的记录,然后B事务向该范围内做了增删记录

小结

在这里插入图片描述

3.锁的不同角度分类

https://www.bilibili.com/video/BV1iq4y1u7vj?p=174
在这里插入图片描述

3.1 从数据操作的类型划分:读锁、写锁

在这里插入图片描述

额外说明:

  • 本质上来说是没有读锁和写锁的,只有排它锁和共享锁;
  • 读操作而言默认是共享锁,但是也可以给读操作上排它锁
  • 写操作就必须是排它锁

0.行级别x锁 和 s锁的兼容性问题

在这里插入图片描述
不管是现有读锁还是写锁,只要有写锁参与都会被阻塞;

1.锁定读

读操作加S锁

在这里插入图片描述

读操作加X锁

在这里插入图片描述

演示1. 两个共享锁

在这里插入图片描述

演示2: 先加共享锁,后加排它锁

在这里插入图片描述

演示3: 先加排它锁,后加共享锁

在这里插入图片描述

8.0 新特性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 写操作

宏观来看,写操作就是加X锁 ;
细节来看,update和delete操作是真正的加排他锁;insert操作只是加隐式锁;
在这里插入图片描述

3.2 从数据操作的粒度划分:表级锁、页级锁、行锁

锁粒度越小,并发度越高;但是同时,管理锁消耗的资源就越多!
在这里插入图片描述

1. 表锁

在这里插入图片描述

(1)表级别S锁和X锁

InnoDB 下的元数据锁

在这里插入图片描述

InnoDB 下表锁

在这里插入图片描述

如何给表上锁演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

表锁下的 读写并发演示

在这里插入图片描述
上面所说的自己,就是给表上锁的事务;

(1) 表级别读锁
在这里插入图片描述
在这里插入图片描述

(1) 表级别写锁
在这里插入图片描述
在这里插入图片描述

(2)意向锁

意向锁是表锁

在这里插入图片描述

意向锁要解决的问题

在这里插入图片描述

  • 如果事务A给数据表中某些记录上了共享锁,会自动给该数据表添加意向共享锁
  • 如果事务A给数据表中某些记录上了排他锁,会自动给该数据表添加意向排他锁

如何添加意向锁

在这里插入图片描述

举例

在这里插入图片描述
意向锁IX和表级S锁互斥
在这里插入图片描述
事务A给表teacher的某行上了排它锁,自动给表上了意向排它锁IX,此时别的事务想要给此表上表级读锁和表级写锁都会被阻塞!

在这里插入图片描述

总结

  • 意向锁是表级锁,是InnoDB引擎自动生成的;
  • InnoDB支持多粒度锁,特定场景下, 表级锁(意向锁)和行级锁共存;
  • 意向排它锁IX,意向共享锁IS
  • 意向锁之间是不互相排斥的;
  • 意向锁和行级锁也是不互相排斥的(和第二条一个意思=> 意向锁和行锁共存)
  • 表级锁意向锁 之间的排斥规则 和读写锁的排斥规则是一样的
  • 意向锁在保证并发性的前提下,实现了行锁和表锁共存 并且 满足事务隔离性 的要求
(3)自增锁

https://www.bilibili.com/video/BV1iq4y1u7vj?p=176&spm_id_from=pageDriver

自增约束字段的插入演示

在这里插入图片描述

三种插入模式讲解

在这里插入图片描述
在这里插入图片描述

针对自增锁并发性低下的三种锁定模式

(1)传统模式
在这里插入图片描述
传统模式下,只要是insert 语句就要持有AUTO-INC锁才能执行;否则排队阻塞;

(2)连续锁定模式

  • 这种模式优化了 插入已知行数的场景;
  • 对于insert xx select xx from 这种仍然需要AUTO-INC锁;
  • 而对于插入行数已知的insert 语句来说,在执行的时候,直接获取行数,表示要插入这么多行先占位!不需要等数据全部插入进来,占好位置后就可以将AUTO-INC锁释放了
    在这里插入图片描述
    (3)锁定模式

在这里插入图片描述

(4) 元数据锁(MDL锁)

在这里插入图片描述
在这里插入图片描述

2.行级锁

  • 只有InnoDB支持行级锁
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

(1)记录锁

在这里插入图片描述
在这里插入图片描述

记录锁的特点就是锁住表中已有的记录;

(2)间隙锁

在这里插入图片描述

由于是间隙锁,因此间隙读锁、间隙写锁没有本质区别;不影响别的事务继续加gap锁:
在这里插入图片描述
这里上锁并非是给某个值上锁,而是给区间(3,8) 上锁;

间隙锁会阻碍insert:
上面锁住了(3,8),因此这里插入6是插不进去的
在这里插入图片描述
如果在最后一行后面上锁,锁区间就是最后一行到正无穷:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

间隙锁可能会造成死锁

如下图所示:
在这里插入图片描述

第一步:在事务A中,给(3,8)区间上间隙读锁;
第二步:在事务B中,给(3,8)区间上间隙读锁;
第三步:在事务B中,在(3,8)区间插入一条记录,被阻塞
第四步:在事务A中,在(3,8)区间插入一条记录,报错,错误日志:产生死锁;

在这里插入图片描述

  • 事务A持有id=1的写锁
  • 事务B持有id=2的写锁
  • 事务A想要获取id=2的写锁,被阻塞
  • 事务B想要获取id=1的写锁,被阻塞

死锁解决方案:

  1. 等待超时
  2. 让步,让最后一个产生死锁的事务回滚(即事务结束),从而事务B可以顺利执行;
(3) 临键锁(Next-key_lock)

https://www.bilibili.com/video/BV1iq4y1u7vj?p=178

间隙锁是开区间,临建锁是闭区间
在这里插入图片描述
临建锁的写法:在这里插入图片描述
在这里插入图片描述

(4) 插入意向锁

在这里插入图片描述

插入意向锁互不排斥:
在这里插入图片描述
在这里插入图片描述

3.页锁

在这里插入图片描述

3.3 从对待锁的态度划分:乐观锁、悲观锁

1.悲观锁

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.乐观锁

在这里插入图片描述
(1)版本机制实现乐观锁
在这里插入图片描述
update 操作会先读取该记录

事务A:

  • 先读,读的时候版本是1
  • 然后进行update,update的时候还是1,说明在读后没有别的事务修改过他
  • 做完修改后,将version + 1

事务B过来:

  • 读是2
  • 进行修改,version也是2,则可以进行修改。
    读和写之间没有别的事务修改它,相当于保证了读和修改的原子绑定

针对的场景

事务A

  • 读的时候,版本是1

事务B

  • 读的时候,版本也是1
  • 修改了,版本变为2

事务A

  • 修改 update xx where version = 1 发现没有了,修改失败;此时再次查询,发现version变成2了,再对version = 2进行修改

(2) 时间戳机制
在这里插入图片描述

在这里插入图片描述
从秒杀案例2看出:
第一次是读,第二次update也是读,也就是说必须保证写的时候版本和读的时候一致才能进行修改;两次读!!!

读写分离场景: 读从机,写主机
在这里插入图片描述
强制读主机,读写保持一致!

高并发场景
在这里插入图片描述

  • 1、多个事务查询某条记录 version = 1;
  • 2、事务A,进行修改 version =2;
  • 3、其他事务再进行修改,发现version不一致了,因此修改失败

在这里插入图片描述

3.4 按照加锁方式进行分类

https://www.bilibili.com/video/BV1iq4y1u7vj?p=180

1.隐式锁

场景1:Insert

  • 事务A,插入一条记录,此时是不加锁的;还未提交
  • 事务B进来了,进行查询,此时会对A插入的记录进行上锁,因此事务B无法访问到;

特点:懒加载;只有被别的事物要访问的时候才会上锁
目的:防止事务A插入的数据在还未提交时,被别的事务访问到;

场景2:插入意向锁

在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值