内容正文:
并发控制
第7章
本章主要内容
本章主要介绍数据库并发操作带来的数据不一致性问题、事务的概念及特性、活锁和死锁问题、数据库系统的封锁技术及封锁协议、并发调度的可串行性与两段锁协议、封锁粒度与多粒度封锁等。
为了充分利用数据库资源,数据库用户对数据库系统并行存取数据,这样就会发生多个用户并发存取同一数据的情况,如果对并发操作不加控制,可能会产生不正确的数据,破坏数据的完整性。因此,数据库管理系统提供并发控制机制,保证数据库的完整性和一致性。
2
目录
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)调度,否则,是不可串行性的调度。