- 关系数据库设计
- DBMS - 数据库规范化
- DBMS - 数据库连接
- 存储和文件结构
- DBMS - 存储系统
- DBMS - 文件结构
- 事务和并发
- DBMS - 事务
- DBMS - 并发控制
- DBMS - 死锁
- 备份和恢复
- DBMS - 数据备份
- DBMS - 数据恢复
- DBMS 有用资源
- DBMS - 快速指南
- DBMS - 有用资源
- DBMS - 讨论
DBMS - 并发控制
在多个事务可以同时执行的多程序环境中,控制事务的并发性非常重要。我们有并发控制协议来确保并发事务的原子性、隔离性和可串行性。并发控制协议可以大致分为两类:
- 基于锁的协议
- 基于时间戳的协议
基于锁的协议
配备了基于锁的协议的数据库系统使用一种机制,通过该机制,任何事务在获取相应锁之前都不能读取或写入数据。锁有两种:
二元锁 - 数据项上的锁可以处于两种状态;要么被锁定,要么未锁定。
共享/排他 - 这种类型的锁定机制根据锁的使用方式区分锁。如果获取数据项上的锁以执行写操作,则它是排他锁。允许多个事务写入同一数据项会导致数据库进入不一致状态。读取锁是共享的,因为没有更改任何数据值。
有四种类型的锁协议可用:
简单锁协议
简单的基于锁的协议允许事务在执行“写”操作之前获取每个对象的锁。事务可以在完成“写”操作后解锁数据项。
预声明锁协议
预声明协议评估其操作并创建需要锁定的数据项列表。在启动执行之前,事务会预先向系统请求它需要的所有锁。如果所有锁都被授予,则事务执行并在所有操作完成后释放所有锁。如果未授予所有锁,则事务回滚并等待直到所有锁都被授予。
两阶段锁定 2PL
此锁定协议将事务的执行阶段分为三个部分。在第一部分,当事务开始执行时,它会请求其所需的锁的权限。第二部分是事务获取所有锁的地方。一旦事务释放其第一个锁,第三阶段就开始了。在此阶段,事务不能再请求任何新锁;它只能释放已获取的锁。
两阶段锁定有两个阶段,一个是增长阶段,其中所有锁都被事务获取;第二个阶段是缩减阶段,其中事务持有的锁被释放。
要声明排他(写)锁,事务必须首先获取共享(读)锁,然后将其升级为排他锁。
严格两阶段锁定
严格 2PL 的第一阶段与 2PL 相同。在第一阶段获取所有锁后,事务继续正常执行。但与 2PL 相比,严格 2PL 在使用后不会释放锁。严格 2PL 保持所有锁直到提交点,并在同一时间释放所有锁。
严格 2PL 没有像 2PL 那样级联中止。
基于时间戳的协议
最常用的并发协议是基于时间戳的协议。此协议使用系统时间或逻辑计数器作为时间戳。
基于锁的协议在执行时管理事务之间冲突对的顺序,而基于时间戳的协议在事务创建后立即开始工作。
每个事务都有一个与其关联的时间戳,并且顺序由事务的年龄决定。在 0002 时钟时间创建的事务将比其后出现的其他所有事务都旧。例如,任何在 0004 进入系统的事务“y”都年轻两秒,并且优先级将给予较旧的事务。
此外,每个数据项都赋予最新的读取和写入时间戳。这使系统能够知道上次对数据项执行“读取和写入”操作的时间。
时间戳排序协议
时间戳排序协议确保事务在其冲突的读写操作中的可串行性。这是协议系统应确保冲突对的任务应根据事务的时间戳值执行的责任。
- 事务 Ti 的时间戳表示为 TS(Ti)。
- 数据项 X 的读取时间戳表示为 R-timestamp(X)。
- 数据项 X 的写入时间戳表示为 W-timestamp(X)。
时间戳排序协议的工作原理如下:
如果事务 Ti 发出 read(X) 操作:
- 如果 TS(Ti) < W-timestamp(X)
- 操作被拒绝。
- 如果 TS(Ti) >= W-timestamp(X)
- 操作执行。
- 所有数据项时间戳更新。
如果事务 Ti 发出 write(X) 操作:
- 如果 TS(Ti) < R-timestamp(X)
- 操作被拒绝。
- 如果 TS(Ti) < W-timestamp(X)
- 操作被拒绝,Ti 回滚。
- 否则,操作执行。
托马斯写规则
此规则指出,如果 TS(Ti) < W-timestamp(X),则操作被拒绝,Ti 回滚。
可以修改时间戳排序规则以使调度视图可串行化。
而不是使 Ti 回滚,“写”操作本身会被忽略。