9.2.2 加锁协议 1、 保证数据一致性的三级加锁协议:0 p- G* }* L* G5 }/ ~7 @
(1) 1级加锁协议要求事务T在修改数据项Q之前必须先对Q加X锁,直到事务结束才释放,事务结束包括正常结束和非正常结束,但事务如果只对Q读而不写,则不需对Q加锁;3 E* E* r+ I0 x3 {, Y0 Y
(2) 2级加锁协议是在1级加锁协议基础上,要求T在读取Q前必须先对其加S锁,读完后立即释放S锁;
, ^. k% u% g8 Z+ O (3) 3级加锁协议是在1级加锁协议基础上,要求在读取Q前必须先对其加S锁,但需等到事务结束后才释放S锁。( G% s6 p# B; f2 B# o7 O
9.2.3 两阶段锁协议
$ p! t( P% ?/ M+ Y/ L+ b% N- j' x- h 1、 两阶段锁(2PL)基本原理如下:
3 k2 s1 r1 Z P5 u% a0 B3 M# v (1) 每个事务的执行过程划分为两个阶段,加锁阶段和解锁阶段;1 o7 _( a& ]% x& W( R5 N
(2) 在加锁阶段,事务可以申请获得任何数据项上的任何类型的锁,但是不允许释放任何锁; t: ]- R8 A5 ~
(3) 在解锁阶段,事务可以释放任何数据上的任何类型的锁,但是不能再申请任何的锁; s: p* |5 m, o$ i
(4) 每个事务开始执行后就进入加锁阶段,当第一次释放锁后,即进入解锁阶段。% q8 N( }. H( W; I, L* a
9.2.4 锁粒度0 ~0 ~1 ]% F+ Y; g
1、 施加X锁和S锁的数据项大小称为锁粒度。: b M; \( f3 F% P2 J9 U
2、 锁粒度越大,系统中可以被锁的数据项就越少,事务的并发执行度也越低,但同时系统的开销也小,相反,当锁粒度越小时,事务的并发度高,但系统开销也较大;
7 h% Z4 z; G' O6 \ 9.3 死锁处理( L, Q8 K3 c6 H# }
9.3.1 死锁预防7 s) n5 R8 a; f5 U4 w& p8 G* ]
1、 一次加锁法) A p8 P& D* J! o" Z0 J& a) [* F1 S
该方法要求每个事务在开始时必须将需要访问的数据项全部加锁,否则不能执行下去,也就是要求事务必须一次性地获得对需要访问的全部数据项的访问权;$ D, v' q9 ]6 M' g
该方法的缺点是:
# P t3 D* d$ v (1) 多个数据项会被一个事务长期锁定独占,导致其他事务无法及时访问这些数据项,降低了系统的并发程度;
2 _5 Q. r; `0 @; E. T (2) 由于很难事先精确知道每个事务在执行过程中需要加锁的全部数据项,只能扩大加锁范围,将事务执行时可能访问的所有数据项全部加锁,进一步降低了系统的并发程度;
6 C/ ?4 y" S( d1 L! o" n: u 2、 顺序加锁法
0 r5 g& L4 {8 ?. l 该方法对数据库中事务访问的所有数据项规定一个加锁顺序,每个事务在执行过程中必须按此顺序对所需数据加锁;
, C. F8 w" U2 @ v; z 该方法的缺点:+ G: P6 m9 [( G5 Z0 C3 A
(1) 数据库中需要加锁的数据项非常多,并且不断变化,维护这些数据项的加锁顺序很困难,代价非常大;
4 ]0 s' y# I& b/ G (2) 事务访问的数据项有时无法事先完全确定,有时很难要求事务按照固定的顺序对这些数据项进行加锁;
8 E R0 C [1 U8 q7 m5 I 9.3.2 死锁检测与恢复
! ]: \/ l5 @# }' C' l 1、 死锁检测
7 y' x+ m7 a# \8 j9 c (1) 可以利用事务等待图进行死锁检测,数据库系统出现死锁当且仅当事务等待图中包含回路,而且回路中的所有事务就是处于死锁的事务;
6 K% i8 v S, ^7 E! d (2) 数据库并发控制子系统动态地构造和维护事务等待图,并周期地检测等待图,如图中有回路,则说明系统中出现了死锁;
( t; o5 {3 z* J( V% S+ a 2、死锁恢复
7 M9 w9 ?) o8 {6 x: Q/ f+ j (1) 当发现死锁存在时,系统可以通过死锁恢复机制将系统从死锁中解救出来,通常是选取一个或几个死锁事务,撤消这些事务,释放其所有的锁,消除事务等待图中的回路,从而解决了系统死锁问题;
+ [( h) F! U, L: B- Q' L (2) 如果决定撤消哪个事务或哪些事务,有两个原则:1 F0 T6 L( |! M# ]
A、 选择处于最多条回路交点处的事务;
& `; Q6 f' C; Y# L6 y B、 选择具有最少撤消代价的事务。
) K/ U5 R- @+ s1 f6 g 9.4 活锁处理
" L8 E3 U6 E/ | 1、如果一个事务在系统不存在死锁的情况下,长期得不到DBMS的获批,处于长时间等待中的情况叫活锁,为了避免活锁,DBMS可采用先来先服务的原则解决。 |