ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 概述 并发访问控制作为数据库领域非常重要的一个问题,目前已经有比较成熟的解决方案,这里介绍三种。 * 悲观并发控制 * 乐观并发控制 * 多版本并发控制 悲观并发控制最常见,也就是我们经常说的悲观锁。 乐观并发控制表示乐观锁,乐观锁不是真正的锁,而表示了一种并发控制策略。 多版本并发控制(MVCC),不同于乐观锁和悲观锁的互斥关系,它能够和乐观锁悲观锁任意一种结合使用,显著提升数据库的读性能。 # 悲观并发控制 - 锁 确保资源在同一时刻只能被一个事务独占。通过悲观锁来实现。 **当一个事务需要操作资源时需要先获得该资源的锁**,保证了在一个事务归还锁之前,其他事务无法获取该资源的锁。 ## 锁类型 * 共享锁(读锁) * 互斥锁(写锁) 为了让数据库的并发能力最大化,数据库设计了两种锁,分别是共享锁和互斥锁。当一个事务获得行记录的共享锁时,只能对行进行读操作。当获取记录行的互斥锁时,能够对行进行读,写操作。 共享锁,互斥锁除了能够限制事务对资源的读写,相互之间还有限制关系。多个事务可以获得同一资源的共享锁,而只能有一个事务获得某一资源的互斥锁。 当事务无法获得资源的锁时,就会陷入阻塞状态。直到其他事务释放锁。 ## 加锁方式 通过图1可以发现,**两阶段锁协议**的加锁和解锁处于两个阶段,在加锁阶段,锁的数量逐个增加。**一次性锁协议**在开始阶段需要获得全部数量的锁 * 一次性锁协议 * 事务开始时,一次性申请所有的锁,无法获取部分数据的锁时,无法开启事务 * 提交事务时释放所有锁 * 避免了死锁 * 并发性不高,事务中的记录被加锁,从事务开始到提交 * 两阶段锁协议 * 整个事务分为两个阶段,第一阶段是从开启事务开始,到提交事务/回滚结束,只能加锁,不能解锁。第二阶段只能解锁。 * 出现了死锁 * 并发性相比一次性锁协议有明显提升 * 提升性能考虑,在事务中操作数据的顺序,应当按照热点升序。参考图2的库存表记录 ![](https://box.kancloud.cn/fe1eaf3f0412d8aaec6ef957fa31f207_707x362.png) :-: 图1 ![](https://box.kancloud.cn/cdf0a028895f88fa475e67bf513a7c78_726x362.png) 图2 ## 死锁 悲观锁的在解决事务并发的同时,引入了死锁的问题。 解决死锁的两种策略, 1. 预防死锁的发生 2. 发生死锁之后的处理 ### 预防死锁 1. 事务开始时将涉及到的所有资源原子性锁定。 2. 抢占加事务回滚。 每个事务被开启时,获得数据库分配的一个时间戳。事务之间触发死锁时,数据库通过对比事务的时间戳来执行不同的方案。 * wait-die。如图3。1 等待另一个事务释放锁。2 保持当前时间戳当前事务回滚。 * round-wait。如图4。1 另一个事务立马回滚。2 当前事务等待。 ![](https://box.kancloud.cn/a2d55843113b3d6b7e51e627fcafed05_848x783.png) 图3 ![](https://box.kancloud.cn/7d8a895086bedacdfb85159b61b23310_840x665.png) 图4 ### 死锁检测和修复 当预防死锁的机制无法生效时,数据库需要有一个检测事务是否进入死锁状态,并解决死锁问题的机制。 ## 锁的粒度 根据锁定的数据范围将锁粒度分为数据库锁,表锁,行锁。 * 父节点被加锁时,所有子节点会被加上隐式锁。避免子节点被加锁 * 子节点被加锁时,对应的父节点会被加上意向锁。避免父节点被加锁。意向锁之前完全不会互斥 # 乐观并发控制 乐观并发控制也成为乐观锁,但跟悲观锁不一样,乐观锁并不是真正的锁,只是一种并发控制策略。 ## 实现策略 1. 在数据中新增字段version,表示当前的数据版本,每次数据更新,version值会+1 2. 事务a读取该数据,通过字段version获得数据版本为1 3. 事务a写入之前校验数据版本是否为1,1的情况下更新数据,同时更新字段version+1;否则终止事务a,数据更新失败。 # MVCC 多版本并发控制,InnoDB支持多种隔离级别,其中的重复读 repeatable read 是通过MVCC实现的。 “版本“指的是事务ID(translate ID),数据库维护累计的事务数量,每开启一个事务,数量累加。InnoDB下数据的记录格式,除了字段本身之外,额外维护了两个字段 * DATA_TRX_ID:最新一次更新该数据行的事务ID * DATA_ROLL_PTR:指向undo Log中旧版本数据的指针 ![](https://box.kancloud.cn/fd1d075eae496bd82fe88aa12edaa98c_821x304.png) ## 参考资料 [浅谈数据库并发控制 - 锁和 MVCC](https://draveness.me/database-concurrency-control)