7.4活锁与死锁 课件(共21张PPT)-《数据库应用技术-SQL Server》同步教学(人民邮电版)

资源下载
  1. 二一教育资源

7.4活锁与死锁 课件(共21张PPT)-《数据库应用技术-SQL Server》同步教学(人民邮电版)

资源简介

(共21张PPT)
并发控制
第7章
本章主要内容
本章主要介绍数据库并发操作带来的数据不一致性问题、事务的概念及特性、活锁和死锁问题、数据库系统的封锁技术及封锁协议、并发调度的可串行性与两段锁协议、封锁粒度与多粒度封锁等。
为了充分利用数据库资源,数据库用户对数据库系统并行存取数据,这样就会发生多个用户并发存取同一数据的情况,如果对并发操作不加控制,可能会产生不正确的数据,破坏数据的完整性。因此,数据库管理系统提供并发控制机制,保证数据库的完整性和一致性。
目录
01
事务
02
并发控制
03
封锁与
封锁协议
04
活锁与死锁
05
并发调度的可串行性与两段锁协议
06
封锁粒度与多粒度封锁
07
SQL Server的并发控制机制
活锁与死锁
第7章
04
7.4.1 活锁
在并发事务处理过程中,如果事务T1已在数据对象R上加锁,事务T2又请求为数据对象R加锁,那么事务T2进入了等待状态,接着事务T3也请求为数据对象R加锁,当事务T1释放了数据对象R上的锁之后,系统首先响应了事务T3的请求,允许事务T3对数据对象R加锁,此时事务T2仍然等待,之后事务T4又请求封锁数据对象R,当事务T3释放了数据对象R的封锁之后,系统又响应了事务T4的请求……事务T2则有可能永远等待而无法执行,这就是活锁的情况。
7.4.1 活锁
避免活锁的简单方法是采用先来先服务的策略,按照请求封锁的次序对事务排队,一旦数据对象上的锁被释放,就使申请队列中的第一个事务获得锁。
7.4.2 死锁
事务T1对数据对象R1加了锁,事务T2对数据对象R2加了锁,之后,事务T1又申请对数据对象R2加锁,因为事务T2已经对数据对象R2加锁,所以事务T1必须等待事务T2释放数据对象R2上的锁。接着,事务T2又申请对数据对象R1加锁,因为事务T1已经封锁了数据对象R1,事务T2也必须等待事务T1释放数据对象R1上的锁,这样就出现了事务T1和事务T2永远处于相互等待状态,始终无法结束,这样的情况被称为死锁。
7.4.2 死锁
1.死锁的预防
死锁预防机制的思想是:避免并发事务互相等待其他事务释放封锁的情况出现,保证数据库系统永不进入死锁状态。预防死锁主要有一次封锁法和顺序加锁法两种。
(1)一次封锁法
一次封锁法要求每个事务开始执行之前,一次性将所有要用的数据对象全部加锁,否则事务就不能继续执行。
7.4.2 死锁
(2)顺序加锁法
预先对所有数据对象规定一个加锁顺序,所有的事务都按这个顺序进行加锁,在释放时按逆序进行。顺序加锁法可以有效地防止死锁,但是也存在一些问题。数据库系统中可封锁的数据对象很多,并且随着数据的插入、删除等操作而动态变化,要维护这些资源的封锁顺序非常困难,系统维护的成本很高。
7.4.2 死锁
2.死锁的检测与解除
在数据库系统中,诊断死锁一般使用超时法和事务等待图法。
(1)超时法
当一个事务等待加锁的时间超过了规定的时限,就被认为发生了死锁。超时法实现简单,但是设置判断死锁的时限是非常困难的,如果设置的时限太长,那么发生死锁以后不能及时发现;如果设置的时限太短,那么由于其他原因导致的事务等待超时也会被误认为发生了死锁。
7.4.2 死锁
(2)事务等待图法
事务等待图是一个有向图G=(T,E),T为节点的集合,每个节点表示正在运行的事务,E为边的集合,每条有向边表示事务等待的情况。若事务T1等待事务T2,则在T1和T2之间画一条有向边,由T1指向T2。事务等待图动态地反映了所有事务的等待情况,并发控制子系统周期性地检测事务等待图,若发现图中存在回路,则表示系统中出现了死锁。图7.1中,事务T1等待事务T2,事务T2等待事务T1,这就产生了死锁。
解决方法:数据库系统选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有锁,使需要这些数据对象的其他事务可以继续运行下去;然后,对撤销的事务进行回滚操作,即对它所执行的数据修改操作进行恢复处理。
并发调度的可串行性
与两段锁协议
第7章
05
7.5 并发调度的可串行性与两段锁协议
数据库系统对并发事务的执行次序是随机的,不同的执行次序可能会产生不同的运行结果。通常情况下,如果一个事务在执行过程中没有与其他事务并发运行,那么该事务的执行就不会受到其他事务的干扰,运行结果就是正常的或者是预想的。
当多个事务串行执行时,事务的运行结果一定是正确的。
7.5.1 并发调度的可串行性
定义7.2 调度(Schedule)是指事务的执行次序。如果多个事务依次执行,则称为事务的串行调度。如果多个事务同时执行,则称为事务的并发调度。
定义7.3 如果多个事务的并发运行结果与按某一次序串行地执行这些事务时结果相同,称这种调度策略为可串行性(Serializable)调度,否则,是不可串行性的调度。
可串行性是并发事务正确性的判别准则,按照这个准则的规定,一个给定的并发调度,当且仅当它是可串行性时,才认为是正确的调度。
7.5.1 并发调度的可串行性
表7.7中,A和B的初始值都是50,按串行调度(一)的执行顺序调度事务T1和T2,A=52,B=51。按串行调度(二)的执行顺序调度事务T1和T2,A=51,B=52。两种调度的结果虽然不同,但由于它们是串行调度的,因此都是正确的调度。
7.5.1 并发调度的可串行性
表7.8的左侧两栏中,两个事务是交错执行的,执行的结果是A=51,B=51,由于这个结果与按串行调度的两种执行结果都不同,因此是错误的调度;表7.8的右侧两栏中,两个事务也是交错执行的,其执行结果是A=52,B=51,这与表7.7中串行调度(一)的执行结果相同,因此是正确的调度。
7.5.2 两段锁协议
为保证并发操作的正确性,数据库管理系统的并发控制机制普遍采用加锁方法实现并发操作调度的可串行性,从而保证调度的正确性。保证并发调度可串行性的封锁协议是两段锁协议。
两段锁协议规定所有的事务应遵守如下规定:
(1)在对任何一个数据对象进行读写操作之前,事务必须申请对该数据对象进行封锁;
(2)在释放某个锁之后,事务不能再对任何数据对象加锁。
7.5.2 两段锁协议
两段锁协议要求所有事务必须分两个阶段对数据对象加锁和解锁。
第一阶段是加锁阶段,也称扩展阶段。在这一阶段中,事务可以申请获得任何数据对象上的任何类型的锁,但是不能释放任何锁。
第二段是解锁阶段,也称收缩阶段。在这一阶段中,事务可以释放任何数据对象上的任何类型的锁,但不能再申请任何锁。
7.5.2 两段锁协议
【例7.2】有如下两个事务的封锁序列。
事务T1的封锁序列如下所示,释放锁在所有加锁之后,因此它遵守两段锁协议。
XLOCK(A)→SLOCK(B)→XLOCK(C)→UNLOCK(B)→UNLOCK(A)→UNLOCK(C)
事务T2的封锁序列如下所示,在释放B上的锁后,又申请对C加锁,因此它不遵守两段锁协议。
XLOCK(A)→SLOCK(B)→UNLOCK(B)→SLOCK(C)→UNLOCK(A)→UNLOCK(C)
7.5.2 两段锁协议
【例7.3】采用两段锁协议保证了事务T1和T2为可串行性调度。
由于遵守两段锁协议,事务T1在成功获得全部数据对象A和B并使用完毕后,才会释放锁,并且不再申请加锁。事务T1在处理完数据对象A和数据对象B后,事务T2才能执行对数据对象A和数据对象B的操作,显然这个调度是一个可串行性调度,也能够成为正确的调度。
7.5.2 两段锁协议
两段锁协议是并发调度可串行性的充分条件,但不是必要条件。若并发事务的调度遵守两段锁协议,那么这个调度一定是可串行性调度;若并发事务的调度并不遵守两段锁协议,也有可能是可串行性调度。
两段锁协议和防止死锁的一次封锁法有类似之处,一次封锁法要求每个事务必须一次性将所有要使用的数据对象全部加锁,否则就不能继续执行,因此一次封锁法遵守两段锁协议,但两段锁协议并不要求事务必须一次性将所有要用到的数据对象全部加锁,因此,遵守两段锁协议的事务也可能发生死锁。

展开更多......

收起↑

资源预览