数据库复习(10) 并发控制

一、基于锁的协议

1. 锁

本节中考虑两种:

  1. 共享锁(shared lock):若事务T获得了数据项Q上的共享锁(记为S),则它可读但不可写Q。
  2. 排他锁(exclusive lock):若事务T获得了数据项Q上的排他锁(记为X),则既可读也可写Q。

每个事务应当针对子集对数据项Q进行的操作类型申请锁,并由不乏控制管理器授予所需锁后才能操作。
锁相容关系:
数据库复习(10) 并发控制

要访问一个书记想,事务必须首先给数据项加锁,如果其一百倍零一十五加上了不相容的锁,则在所有其他事务持有的不相容类型的锁被释放之前,并发控制管理器不会授予锁。因此该事务将等待,直至其他食物持有的不相容类型锁被释放。

2. 死锁与饿死

数据库复习(10) 并发控制
这样的情况下,锁不会自然取消,需要对T3或T4进行回滚。应当注意到,思索事实上体现了并发控制中的访问冲突,因此它一定程度上是必然会出现的。
饿死(starvation)是指希望对某数据项上X锁的事务因对该数据项上S锁的事务不断插队而不断回滚的情况。使用以下条件能够防止饿死:加锁的条件应该是:

  1. 不存在数据项Q上持有与M型锁冲突事的锁的其他事务
  2. 不存在一个等待对数据项Q枷锁且现由于Ti申请加锁的事务

3. 两阶段*协议(2PL protocol)

其要求每个事务(注意2PL的单位)分两个阶段:

  1. 增长阶段:事务仅获得锁,不释放锁
  2. 缩减阶段:事务仅释放锁,不获得锁

*点(lock point):在调度中,该事务获得其最后枷锁的位置
多事务可以根据其*点进行排序,而这个顺序就是事务的一个可串化顺序

  • 严格(strict)两阶段*协议:用于防止级联回滚
    要求事务持有的排他锁必须在事务提交之后方可释放
  • 强(rigorous)两阶段*协议:
    要求事务提交之前不得释放恩和锁

锁转换

  • 可以在增长阶段进行锁升级,将共享锁升级为排他锁
  • 可以在缩减阶段进行锁降级,将排他锁转换为共享锁

锁转换一定程度上防止死锁的发生

4. 锁管理器

数据库复习(10) 并发控制
上图就是所管理器中锁表的数据结构,其中每个数据项被映射到以溢出链为实现方式的哈希表中,数据项指向在它身上加的(将要加的)一系列锁。

  • 黑色举行代表已加的锁,白色矩形则代表仍等待的request
  • 锁表会记录锁的类型
  • 新的request被添加在数据项指向链表的末尾,并在与之前的锁兼容时被授权(变黑)
  • 解锁操作在数据项上对应地删除举行
  • 如果事务被终止,所有正在等待的request都会被删除

5. 基于图的协议

基于图协议看重的是访问数据项的顺序,因而对所有数据项集合D={d1,d2,...,dn}D=\{d_1,d_2,...,d_n\},满足偏序\rightarrow:
didj,访访di,访dj如果d_i\rightarrow d_j,则任何访问两者的事务必须首先访问d_i,再访问d_j
这样的偏序关系构成的有向无环图成为数据库图(database graph),应当注意的是,简单树形协议只使用排他锁。

树形协议的加锁规则

  1. Ti首次加锁可以对任何数据项进行
  2. 此后Ti对数据项Q加锁的前提是Ti当前持有Q的父项上的锁
  3. 对数据项的解锁可以所示进行
  4. 数据项被某个事务加锁并解锁后,该事务不能再为该数据项加锁

例子:
数据库复习(10) 并发控制
基于图的加锁协议不保证可恢复性无级联回滚

二、多粒度与意向锁

某些情况下需要把多个数据项聚为一组,将它们作为一个同步单元,因此系统应当定义多粒度的机制,允许数据项以不同大小被同步操作。多粒度树中的非叶节点表示与后代相关联的数据。
数据库复习(10) 并发控制
在上图中,从上到下的层级分别问数据库,类型空间,数据表(文件)和元组。