🚀 Database
1、数据库基础
1.1 事务的概念和特性
1.2 锁
1.3 锁协议
1.4 事务日志
1.5 MVCC实现原理
1.6 基础知识
1.6.1 三范式
1.6.2 多表连接方式
1.6.3 存储过程
1.6.4 TRUNCATE和DROP的区别
1.6.5 触发器
1.6.6 视图
2、MySQL
2.1 索引
2.2 索引组织表
2.3 InnoDB和MyISAM的区别
2.4 Checkpoint技术
2.5 宕机恢复原理
2.6 数据库优化
2.7 分库分表
2.8 一致性哈希算法
2.9 主从复制
3、Redis
3.1 概述
3.1.1 为什么Redis单线程还这么快
3.1.2 Redis数据类型
3.1.3 持久化机制
3.1.4 过期机制和内存淘汰策略
3.2 线程模型
3.3 分布式问题
3.3.1 Redis实现分布式锁
3.4 缓存异常
3.4.1 缓存击穿、缓存雪崩
3.5 高可用
3.5.1 主从复制
3.5.2 哨兵模式
3.5.3 集群模式
-
+
游客
注册
登录
锁协议
## 1 三级封锁协议 > 三级封锁协议就是三个不同级别的封锁协议,他们是以何时加锁,何时解锁来区分的。 ### 1.1 一级封锁协议 #### 1.1.1 含义 1. 事务 $T$ 在**修改数据 $R$ 之前必须先对其加 $X$ 锁**,直到**事务结束才释放**,事务结束包括正常结束(Commit)和非正常结束(Rollback)。 2. 在**一级封锁协议中**,如果**仅仅是读数据而不对其进行修改**,是**不需要加锁**的。 3. 一级封锁协议可以**解决更新丢失问题**,但是他**不能保证可重复读和不读脏数据**。 #### 1.1.2 示例 ##### 1.1.2.1 不使用锁导致的更新丢失问题 ![](/media/202106/2021-06-25_110640.png) ##### 1.1.2.2 使用一级锁解决更新丢失问题 ![](/media/202106/2021-06-25_110719.png) ![](/media/202106/2021-06-25_110731.png) ##### 1.1.2.3 为什么一级锁不能解决脏读问题 脏读例子: ![](/media/202106/2021-06-25_110838.png) 用一级锁的情况: ![](/media/202106/2021-06-25_110903.png) ### 1.2 二级封锁协议 #### 1.2.1 含义 1. **在一级封锁协议之上**,事务 $T$ 在**读取数据 $R$ 之前必须先对其加 $S$ 锁**,**读完后方可释放 $S$ 锁**。 2. 二级封锁协议除了**可以解决丢失更新问题**,还可以进一步**解决脏读问题**。 3. 但在二级封锁协议中,由于**读完数据后即可释放 $S$ 锁**,所以他**不能保证可重复读**。 #### 1.2.2 示例 ##### 1.2.2.1 使用二级锁解决脏读问题 ![](/media/202106/2021-06-25_111502.png) ##### 1.2.2.2 为什么二级锁不能解决不可重复读的问题 不可重复读例子: ![](/media/202106/2021-06-25_111609.png) 使用二级锁的情况: ![](/media/202106/2021-06-25_111627.png) ### 1.3 三级封锁协议 #### 1.3.1 含义 1. 在**一级封锁协议之上**,事务 $T$ 在**读取数据 $R$ 之前必须先对其加 $S$ 锁**,直到**事务结束才释放**。 2. 三级封锁协议除了**解决丢失修改问题**和**脏读问题**,还进一步解决了**不可重复读问题**。 3. 因为三级锁协议相当于**完全串行化**,即**一个事务开始了**,**其他事务都完全不能开始运行**,**无论是读还是写**,**那么就必定不会出现不可重复读的问题了**。 4. 三级锁协议的**完全串行化**,也就是为了**解决并行化带来的问题**,直接**不使用并行**,**改为串行执行**。 ## 2 两段锁协议 ### 2.1 含义 1. 两段锁协议规定所有事务都必须遵循以下规则: 1. 在**对数据进行读、写之前**,首先**要申请并获得对该数据的锁**。 2. 在**释放一个锁之后**,**事务不能再申请和获得其它任何锁**。 2. 这些规则将对数据的加锁和解锁操作分为两个阶段: 1. 第一阶段是**扩展阶段**: 1. 即**获得锁的阶段**,这一阶段的事务**可以获得任何数据项上的任何类型的锁**,但是**不能释放**。 2. 其实也就是该阶段可以进行加锁操作,在**对任何数据进行读操作之前要申请获得$S$锁**,在进行写操作之前要申请并获得$X$锁,如果加锁不成功,则**事务进行等待状态**,**直到加锁成功才可以继续执行**,就是**加锁后不能再解锁了**。 2. 第二阶段是**收缩阶段**: 1. 即**释放锁的阶段**,这一阶段事务**可以释放任何数据项上的任何类型的锁**,但是**不能申请**。 2. 当**事务释放一个锁之后**,事务**进入收缩阶段**,在该阶段**只能进行解锁而不能再进行加锁操作**。 3. 如果所有事务**都遵守两段锁协议**,那么**这些事务的交叉调度都是可串行化的**。 > 如果一个并行调度的结果等价于一个串行调度的结果,那么称这个并行调度为可串行化的。 ### 2.2 示例 ![](/media/202106/2021-06-25_121217.png) ### 2.3 优缺点 #### 2.3.1 缺点 1. **遵循两段锁协议的事务有可能发生死锁**,例如两个事务**都坚持请求对对方已经占有的数据加锁**,这样**就会导致死锁**。 2. 为此又有了**一次封锁法**,他要求**事务必须一次性将所有要使用的数据全部加锁**,**否则就不能继续执行**。 3. 因此,**一次封锁法遵守两段锁协议**,但**两段锁协议并不要求事务必须一次性将所有要使用的数据全部加锁**,这一点是与一次封锁法不同的地方。 ## 参考文献 1. [mysql: 三级封锁协议](https://zhuanlan.zhihu.com/p/26960178)。 2. [数据库三级封锁协议](https://hongscar.github.io/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%89%E7%BA%A7%E5%B0%81%E9%94%81%E5%8D%8F%E8%AE%AE.html)。 3. [两阶段加锁协议](https://lihuimintu.github.io/2019/05/06/Two-Phase-Locking)。
ricear
2021年6月25日 14:26
©
BY-NC-ND(4.0)
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码