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

1.并发控制的概述

事务是并发控制的基本单位,保证事务的ACID特性是事务处理的重要任务,而事务的ACID破坏的可能原因之一是多个数据对事务的并发控制造成的。所以为了保证事务的一致性和隔离性,数据库系统需要对并发操作进行正确的调度。

并发控制带来的数据不一致性包括数据丢失、不可重复度和“脏读”。

数据丢失

两个事务T1、T2读同一数据并修改,T2提交的结果破坏了T1提交的结果,导致数据的丢失。例如在甲乙两个售票点中,事务T1和T2所读到的票余额都为16,T1购票后把余票15写回数据库,T2购票后也吧余票15写回数据库,这就造成了T1数据的丢失。

不可重复读

不可重复读是指事务T1读取数据后,事务T2执行更新操作,使T1无法再读前一次读取的结果。三种情况如下:

  • 事务T1读取数据后,T2对其进行了修改
  • 事务T1读取数据后,T2删除了部分数据
  • 事务T1按某条件读取数据后,T2插入了一些数据,插入数据满足T1读取条件

可重复读是指在一次事务内,对同一条记录的读取,得到的结果都是一样的。

读“脏”数据

读“脏”数据是指事务T1修改某一数据并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤销,这是T1修改的数据恢复原值,T2读到的数据与数据库中的数据不一致,这时候T2读到的数据就是“脏数据”,即与数据库不一致的数据。

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

2.封锁

封锁是实现并发控制的一个非常重要的技术。所谓封锁就是事务T在对某个数据对象操作之前向系统发出请求对其加锁,加锁后,在T事务释放锁前,其他事务不能更新此数据对象。

基本封锁类型有排它锁(Exclusive Locks,简记为X锁)和共享锁(Share Locks,简记为S锁)

  • 排他锁又称为写锁。
    若事务T对数据数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能对A加锁,直到T释放A的锁为止。这就保证了其他事务在A释放前不能再读取和修改A。
  • 共享锁又称读锁。
    若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能在对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了事务执行时读到的A数据是正确的。

3.封锁协议

在运用X锁和S锁这两种锁对数据对象进行加锁时,还需要约定一些规则。例如,何时申请X锁或S锁、持续时间、何时释放等。这些规则称为封锁协议。

一级封锁协议

一级封锁协议是指,事务T在修改数据R之前必须对其加X所,直到事务结束才释放。事务的结束包括正常结束(commit)和非正常结束(rollback)。

一级封锁协议可以防止丢失数据,并保证事务T是可恢复的。如果仅仅读而不对其修改是不需要加锁的,所以它不能保证可重复读和不读“脏”数据。

二级封锁协议

二级封锁协议是指,在一级封锁协议基础上增加事务T在读取R之前必须先对其加S锁,读完后即可释放S锁。

二级封锁协议除了防止数据丢失修改,还可进一步防止读“脏”数据。由于读完数据化即可释放S锁,所以它不能保证可重复读。

三级封锁协议

三级封锁协议是指,在一级封锁协议的基础上增加事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。

三级封锁协议除了可以防止丢失修改和读“脏”数据外,还进一步防止了不可重复读。


以上三种协议主要区别在于什么操作需要申请封锁,以及何时释放锁(即持锁时间)。总结表如下图,表中指出了不同封锁协议使事务达到一致性级别是不同的,封锁协议级别越高,一致性程度越高。

数据库原理第十一章---并发控制_第1张图片

4.死锁和活锁

和操作系统一样,封锁的方法可能引起活锁和死锁等问题。

活锁

如果事务T1封锁了R,事务T2也请求封锁R,事务T3也申请封锁R,于是T2、T3等待,当T1释放R之后首先批准了T3,T2仍在等待,这时T4又请求封锁R,当T2释放之后又批准了T4的请求…T2有可能永远等待,这就是活锁的例子。

避免活锁的简单方法是采用先来先服务的策略。

死锁

如果事务T1封锁了R1,事务T2封锁了R2,然后T2申请封锁T1,这时候T2就在等待,接着T1又申请封锁R2,这时T2也需要等待,这就造成了T1等T2,而T2又等T1的局面,T1和T2永远不可能结束,形成死锁。

目前解决死锁问题主要有两种方法:一类是采取一定措施来预防死锁的发生,另一类是允许发生死锁,采用一定手段定期诊断系统中有无死锁,若有则解除。

死锁的预防

要预防首先要找出产生死锁的原因:当两个或多个事务都已封锁了一些事务对象,然后有再对已经封锁的数据对象请求封锁,这就造成了死锁。因此防止死锁其实就是要破坏死锁产生的条件。主要有以下两种方法

  • 一次封锁法
    一次封锁法要求每个事物必须一次性将所有要使用的数据全部加锁,否则不能继续执行。存在的问题:扩大了封锁范围,降低了系统的并发度,且难确定封锁范围。
  • 顺序封锁法
    顺序封锁法是预先对数据对象规定一个封锁顺序,所有事物按照这个顺序封锁。存在的问题:涉及的对象多,维护起来麻烦,难以确定封锁对象。

对于以上两个方法都不太适合数据库的特点,因此解决死锁问题普遍采用诊断并解除的方法。
死锁的诊断与解除

数据库系统中诊断死锁的方法与操作系统类似,一般使用超时法或事物等待图法。

  • 超时法
    超时法即给一个事务设置等待时间限制,如果超过了这个限制,就认为发生了死锁。超时法实现简单,但不足也很明显,就是很容易误判。
  • 等待图法

数据库管理系统的并发控制子系统一旦检测到系统中存在死锁,通常解除的方法为:选择一个死锁代价最小的事务,将其撤销,释放其事务持有的所有锁,使其他事务得以持续运行下去。

5.并发调度的可串行性

数据库系统对事物并发事物不同的调度可能会产生不同的结果,那么什么样的调度室正确的呢?显然,串行调度是正确的。执行结果等价于串行调度也是正确的。这样的调度叫做可串行调度。

串行即按照一定的顺序

可串行调度

多个事物的并发执行是正确的,当且仅当其结果与按某一次序串行地执行这些事物时的结果相同,这种调度策略为可串行调度

可串行性事物是并发事物正确调度的准则。按这个准则规定,一个给定的并发调度,当且仅当它是可串行的,才认为是正确的。

冲突可串行调度

冲突是指:不同事物对同一个数据的读写操作和写写操作。

一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事物不冲突操作的次序得到另一个调度Sc’,如果Sc’是串行的,称调度Sc为冲突可串行化的调度。若一个调度是冲突可串行化,则一定是可串行化的调度。因此可以用这种方法来判断一个调度是否是冲突可串行化的。

冲突可串行化调度是可串行化调度的充分条件,不是必要条件。

6.两段锁协议

为了保证并发调度的正确性,数据库管理系统的并发控制机制必须提供一定的手段来保证调度室可串行化的。目前数据库管理系统普遍采用两段锁(Two Locking,简称2PL)协议的方法实现并发调度的可串行性,从而保证调度的正确性。

所谓两段锁协议是指所有事物必须分两个阶段对数据项加锁和解锁:

  • 对任何数据进行读、写操作之前,首先申请并获得对该数据的封锁。
  • 在释放一个锁之后,事物不再申请获得其他封锁。

所谓两段锁的含义是事物分为两个阶段:

  • 第一阶段是获得锁,也称为扩展阶段,在这个阶段事物可以申请获得任何数据项上任何类型的锁,但不能释放任何锁。
  • 第二阶段是释放锁,也称为收缩阶段,在这个阶段事物可以释放任何数据项上任何类型的锁,但不能申请任何锁。

事物遵守两段锁协议是可串行化调度的充分条件,二不是必要条件。

7.封锁的粒度

封锁对象的大小称为封锁粒度。

封锁的对象可以是逻辑单元也可以是物理单元。以关系数据库为例,封锁对象可以是这样一些逻辑单元:属性值、属性值得集合、元组、关系索引项等,也可以是这样一些物理单元:页、物理记录。

封锁粒度与系统的并发度和并发控制的开销密切相关。直观地看,封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度越小,系统开销也越小;反之,封锁粒度越小,并发度越高,系统开销也就越大。

多粒度封锁

多粒度封锁是指一个数据库系统同时支持多种封锁粒度供不同的事物选择。

考虑多粒度封锁时,首先定义如下多粒度树。多粒度树的根结点是整个数据库,表示最大数据粒度。叶结点表示最小数据粒度。
数据库原理第十一章---并发控制_第2张图片
多粒度封锁的封锁协议:多粒度封锁协议允许多粒度树中的每个结点被独立地加锁。对一个结点加锁意味着这个结点的所有后裔结点也被加以同样类型的锁。因此多粒度封锁中一个数据对象可能有两种方式封锁,显示封锁和隐式封锁。

显示封锁是应事物的要求直接加到数据对象上的锁,隐式封锁时该数据对象没有被独立加锁,是由于其上级结点加锁而使该数据对象加上了锁。

多粒度封锁方法中,显示封锁和隐式封锁效果是一样的,因此系统检查封锁冲突时不仅要检查显示封锁还要检查隐式封锁。对某个数据对象加锁时,系统要检查其上下级结点的是否有冲突,这样检查效率很低,因此引入了意向锁

意向锁

意向锁的含义是如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁,对任一结点加锁时,必须先对它的上层结点加意向锁。

常见的意向锁有以下三种:
数据库原理第十一章---并发控制_第3张图片

IS锁

如果一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁

IX锁

如果对一个对象加IX锁,表示它的后裔拟(意向)加X锁

SIX锁

如果对一个对象加SIX锁,表示对它加S锁再加IX锁,即SIX=S+IX(读整个表,个别写)。

8.其他并发控制

你可能感兴趣的:(数据库)