你的浏览器不支持本网站所要求的功能, 现在看到的是本网站简化版本.

为了获得最佳体验, 请使用最新的Chrome, Safari, Firefox 或 Edge 浏览器.

6. 数据库保护

6.4 数据库并发控制

Powered by impress.js
Ver. 2408

### 并发控制 - 为保证事务的隔离性和一致性 - 数据库管理系统需要正确调度并发操作
### 例 1 - 考虑飞机订票系统中的一个活动序列: - 甲售票点 (事务 T1) 读出机票余额 A, 设 A=16 - 乙售票点 (事务 T2) 读出机票余额 A, 也为 16 - 甲卖出一张机票, 余额 A 为 15, 把 A 写回数据库 - 乙卖出一张机票, 余额 A 为 15, 把 A 写回数据库 - 导致数据库的不一致
### 并发导致的不一致性 - 丢失修改 - 不可重复读 - 读 "脏" 数据
### 丢失修改 (lost update) - 两个事务 T1 和 T2 读入同一数据并修改 - T2 提交的结果破坏了 T1 提交的结果 - 导致 T1 的修改丢失
### 不可重复读 (non-repeatable read) - 事务 T1 读取数据后 - 事务 T2 执行更新操作 - 使 T1 无法再现前一次读取结果
### 不可重复读 - 事务 T1 读取某一数据后, 事务 T2 修改了数据 - 事务 T1 读取某些数据后, 事务 T2 删除了部分记录 - 事务 T1 读取某些数据后, 事务 T2 插入了一些记录
### 读 "脏" 数据 (dirty read) - 事务 T1 修改某一数据并将其写回磁盘 - 事务 T2 读取同一数据后 - 该修改被撤销, 被修改过的数据恢复原值 - T2 读到的数据与数据库中数据不一致
### 常用的并发控制技术 - 封锁 (locking) - 时间戳 (timestamp) - 乐观控制法 (optimistic scheduler) - 多版本并发控制 (multi-version concurrency control, MVCC)
### 封锁协议 - 事务 T 在操作某个数据对象之前 - 向系统发出加锁请求 - 事务 T 释放锁之前 - 其他事务不能更新此数据对象
### 封锁类型有两种 - 排他锁 (exclusive locks, 简称 X 锁) - 共享锁 (shared locks, 简称 S 锁)
### 排他锁 - 写锁 - 若事务 T 对数据对象 A 加上 X 锁 - 则只允许 T 读取和修改 A - 其他任何事务都不能再对 A 加任何类型的锁 - 直到 T 释放 A 上的锁为止 - 保证其他事务在释放锁之前不能再读取和修改 A
### 共享锁 - 读锁 - 若事务 T 对数据对象 A 加上 S 锁 - 则事务 T 可以读 A 但不能修改 A - 其他事务只能再对 A 加 S 锁而不能加 X 锁 - 直到 T 释放 A 上的 S 锁为止 - 保证其他事务可以读 A 但不能修改 A
### 封锁协议 (locking protocol) - 对封锁方式制定不同的规则 - 三级封锁协议 - 不同级别的封锁协议获得不同的系统一致性级别
### 一级封锁协议 - 事务 T 在修改数据 R 之前必须先对其加 X 锁 - 直到事务结束才释放 - 事务结束包括 COMMIT 和 ROLLBACK - 可防止丢失修改 - 并保证事务T是可恢复的
### 二级封锁协议 - 在一级封锁协议基础上 - 增加事务 T 在读取数据 R 之前必须先对其加 S 锁 - 读完后即可释放 S 锁 - 二级封锁协议防止丢失修改 - 进一步防止读 "脏" 数据
### 三级封锁协议 - 在一级封锁协议的基础上 - 增加事务 T 在读取数据 R 之前必须先对其加 S 锁 - 直到事务结束才释放 - 防止丢失修改和读 "脏" 数据 - 进一步防止了不可重复读
### 活锁 - 当事务 T1 锁定了数据 R - 事务 T2 请求锁定 R, 导致 T2 等待 - 事务 T3 请求锁定 R, 系统批准 T3 请求, T2 等待 - 事务 T4 请求锁定 R, 系统批准 T4 请求, T2 等待 - T2 可能永远等待下去
### 避免活锁 - 先来先服务策略 - 封锁子系统按照请求锁的先后顺序对事务排队 - 批准队列中的第一个事务获得锁
### 死锁 - 事务 T1 锁定了数据 R1, 事务 T2 锁定了数据 R2 - T1 请求锁定 R2, T1 等待 T2 释放 R2 上的锁 - T2 申请锁定 R1, T2 等待 T1 释放 R1 上的锁 - T1 和 T2 两个事务永远无法结束
### 解决死锁问题 - 预防死锁 - 允许死锁发生, 但定期诊断与解除
### 预防死锁 - 一次封锁法 - 顺序封锁法
### 一次封锁法 - 每个事务一次性将所有要使用的数据全部加锁 - 降低了系统的并发度 - 难以事先确定事务需要封锁的数据对象
### 顺序封锁法 - 预先对数据对象规定封锁顺序, 如逐级封锁 - 维护封锁顺序非常困难 - 难以事先确定每个事务需要封锁的对象
### 死锁的诊断与解除 - 超时法 - 事务等待图法
### 超时法 - 如果事务等待时间超过规定时限就认为发生死锁 - 有可能误判死锁 - 如果设置的时限过长则无法及时发现死锁
### 事务等待图法 - 有向图 - 节点表示正运行的事务 - 边表示事务之间的等待关系 - 并发控制子系统周期性地生成事务等待图 - 如果图中存在回路则表示发生了死锁 - 选择撤销代价最小的事务
### 并发调度的可串行性 - 可串行化调度 - 执行结果与按照某一顺序串行执行这些事务的结果相同
### 可串行化调度的特性 - 读-写约束 - 写-写约束 - 读-写依赖
### 读-写约束 - 一个事务 T1 读取了一个数据项 X - 在 T1 写入 X 之前 - 任何事务 T2 都不得对 X 进行写操作
### 写-写约束 - 一个事务 T1 对一个数据项 X 进行了写操作 - 在 T1 提交之前 - 任何事务 T2 都不得对 X 进行写操作
### 读-写依赖 - 如果事务 T1 在读取一个数据项 X 的同时 - 事务 T2 对 X 进行了写操作 - 并且 T1 在 T2 提交之前完成 - 那么 T1 的读操作必须重新执行
### 二段锁协议 - 扩展或生长阶段 (growing phase) - 收缩或缩减阶段 (shrinking phase)
### 扩展阶段 - 事务在执行过程中逐渐获取所需的锁 - 一旦释放了就不能再获取新的锁
### 收缩阶段 - 在执行过程中释放已经持有的锁 - 一旦释放了就不能再获取新的锁
![course 6.4 mindmap](img/c06/mindmap-6-4.png)
### 6.4 数据库并发控制 - 为什么需要数据库并发控制? - 什么是“丢失修改”和“不可重复读"? - 什么是排他锁和共享锁? - 三级封锁协议与一级和二级封锁协议有什么区别? - 什么是活锁和死锁? ---- [ 6.3 数据库恢复技术](dbds-6-3.html#/overview) [| 练习 |](dbds-exec.html) [ 7.1 数据库的发展阶段](dbds-7-1.html#/overview)

黑公网安备23010302001726号   黑ICP备2024033110号-1