数据库原理——第十一章:并发控制

参考书目《数据库系统概论(第5版)》

并发控制概述

并发操作带来的不一致性:

  • 丢失修改:T1和T2同时读入并修改,后者的提交覆盖了前者的提交
  • 不可重复读:T1读取了数据A,期间T2修改了数据A,当T1再次读取A时发现与原先不一致
  • 读“脏”数据:T1保存了对A的修改,但在T2读取A的期间,T1对A的操作被撤销导致A恢复原值,从而T2读取的是错误数据

并发控制的主要技术:封锁、时间戳、乐观控制法和多版本并发控制


封锁与封锁协议

封锁就是事务在对某数据对象操作之前先向系统发出请求,对其加锁
基本的封锁类型有:

  • 排他锁又称写锁(简称X锁)
  • 共享锁又称读锁(简称S锁)

封锁协议:

  1. 一级封锁协议:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放
    一级封锁协议可防止丢失修改,并保证事务T是可恢复的,但其不保证可重复读和不读错误数据
  2. 二级封锁协议:在一级封锁协议基础上,增加事务T在读取数据R之前必须先对其加S锁,读完后即可释放S锁
    二级封锁协议除防止了丢失修改,还进一步防止读错误数据,但其不保证可重复读
  3. 三级封锁协议:在一级封锁协议基础上,增加事务T在读取数据R之前必须先对其加S锁,直到事务结束释放S锁
    三级封锁协议除防止了丢失修改,读读错误数据和不可重复读

活锁和死锁

活锁:就是操作系统中的饥饿,使用FCFS来预防活锁
死锁:就是操作系统中的死锁
死锁的预防:

  • 一次封锁法:一次将所有要使用的数据全部加锁
  • 顺序封锁法:先对数据对象规定一个封锁顺序,所有事务都按这个顺序实施封锁

操作系统中采用的预防死锁不适合数据库,因此数据库普遍采用诊断并解除死锁的方法,即允许发生死锁, 然后采用一定手段定期诊断系统中有无死锁, 若有则解除之
死锁的诊断方法:

  • 超时法
  • 等待图法

死锁的解除,通常采用的方法是:选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有锁,使其他事务得以继续运行下去


并发调度的可串行性

可串行化调度:多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行执行这些事务时的结果相同
可串行性是并发事务正确调度的准则。即一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度
若一个调度是冲突可串行化,则一定是可串行化调度


两段锁协议

数据库系统采用两段锁协议(2PL)的方法实现并发调度的可串行性,从而保证调度的正确性
两段锁协议是指所有事务必须分两个阶段对数据项加锁和解锁:

  • 扩展阶段(第一阶段):获得封锁。在对任何数据进行读、写操作之前,首先要申请并获得对该数据的封锁;此阶段,可以申请获得任何数据项上任何类型的锁,但是不能释放锁
  • 收缩阶段(第二阶段):释放封锁。在释放一个封锁之后,事务不再申请和获得任何其他封锁

事务遵守两段锁协议是可串行化调度的充分条件
一次封锁法遵守两段锁协议,但两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务仍可能发生死锁