MySQL数据库原理学习(四十一)
C. 排它锁与排他锁之间互斥
当客户端一,执行update语句,会为id为1的记录加排他锁;客户端二,如果也执行update语句更新id为1的数据,也要为id为1的数据加排他锁,但是客户端二会处于阻塞状态,因为排他锁之间是互斥的。直到客户端一,把事务提交了,才会把这一行的行锁释放,此时客户端二,解除阻塞。
D. 无索引行锁升级为表锁
stu表中数据如下:
我们在两个客户端中执行如下操作:
在客户端一中,开启事务,并执行update语句,更新name为Lily的数据,也就是id为19的记录 。
然后在客户端二中更新id为3的记录,却不能直接执行,会处于阻塞状态,为什么呢?
原因就是因为此时,客户端一,根据name字段进行更新时,name字段是没有索引的,如果没有索引,此时行锁会升级为表锁(因为行锁是对索引项加的锁,而name没有索引)。
接下来,我们再针对name字段建立索引,索引建立之后,再次做一个测试:
此时我们可以看到,客户端一,开启事务,然后依然是根据name进行更新。而客户端二,在更新id为3的数据时,更新成功,并未进入阻塞状态。这样就说明,我们根据索引字段进行更新操作,就可以避免行锁升级为表锁的情况。
5.4.3 间隙锁&临键锁
默认情况下,InnoDB在 REPEATABLE READ事务隔离级别运行,InnoDB使用 next-key 锁进行搜索和索引扫描,以防止幻读。
索引上的等值查询(唯一索引),给不存在的记录加锁时, 优化为间隙锁 。
索引上的等值查询(非唯一普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock 退化为间隙锁。
索引上的范围查询(唯一索引)--会访问到不满足条件的第一个值为止。
注意:间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会
阻止另一个事务在同一间隙上采用间隙锁。
示例演示
A. 索引上的等值查询(唯一索引),给不存在的记录加锁时, 优化为间隙锁 。
B. 索引上的等值查询(非唯一普通索引),向右遍历时最后一个值不满足查询需求时,next-keylock 退化为间隙锁。
介绍分析一下:
我们知道InnoDB的B+树索引,叶子节点是有序的双向链表。假如,我们要根据这个二级索引查询值为18的数据,并加上共享锁,我们是只锁定18这一行就可以了吗?并不是,因为是非唯一索引,这个结构中可能有多个18的存在,所以,在加锁时会继续往后找,找到一个不满足条件的值(当前案例中也
就是29)。此时会对18加临键锁,并对29之前的间隙加锁。
C. 索引上的范围查询(唯一索引)--会访问到不满足条件的第一个值为止。
查询的条件为id>=19,并添加共享锁。此时我们可以根据数据库表中现有的数据,将数据分为三个部
分:
[19]
(19,25]
(25,+∞]
所以数据库数据在加锁是,就是将19加了行锁,25的临键锁(包含25及25之前的间隙),正无穷的临键锁(正无穷及之前的间隙)。
相关文章
- Flask 学习-93.cookie 有效期设置
- JavaScript 学习-50.实现页面菜单拖放(Drag 和 Drop)
- 支持向量机SVM算法的学习记录
- Flask 学习-94.Flask-SQLAlchemy 按日期时间查询
- Flask 学习-95.Flask-SQLAlchemy 查询今天当天的数据
- Flask 学习-96.Flask-SQLAlchemy 判断查询结果是否存在的几种方式
- Flask 学习-97.Flask-SQLAlchemy 排序 order_by()
- Flask 学习-98.Flask-SQLAlchemy limit() 限制返回条数
- pytest文档81 - 如何管理Captured logging日志
- 「 简述网上常见的几种linux的网站管理面板 」
- Spring学习笔记 - IOC
- 「 【Docker】如何处理宝塔docker管理器未启动 」
- 「 【Docker】利用宝塔docker管理器搭建为知笔记(docker安装为知笔记) 」
- JVM字节码学习笔记——class 文件结构
- C语言学习 第二章 安装编译器及运行环境
- MacOS Monterey12.1-12.3版本连接L2TP无法正常访问公司内网非完美解决方案(详细)
- Yate for Mac(音乐标签管理工具) 6.13中文版
- 开源一个个人写的小工具,用于rap(一个接口管理平台)转ts代码格式用
- 【学习笔记】MySQL学习笔记-服务启动与SQL篇
- 【学习笔记】JDBC MySQL8.0连接 – Java