本篇介绍如何进行并发控制。
——封锁。
1,封锁
(1)封锁就是事务T在对某数据对象(例如:表、记录)操作之前,先向系统发出请求,对其加锁
(2)加锁后事务T就对数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象
2,封锁类型
不同的锁有不同的控制功能;即,一个事务对数据对象加锁后可有怎样的控制由它的封锁类型决定。
(1)排他锁(简称X锁,或写锁)
a.含义:若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。
b.功能:保证其他事务在事务T释放数据对象A上的锁之前不能在读和修改A。
(2)共享锁(简称S锁,或读锁)
a.含义:若事务T对数据对象A加上S锁,则其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁
b.功能:保证其他事务可以读数据对象A,但在事务T释放A上的S锁之前不能对A做任何修改、
关注点在哪里,一级封锁协议的关注点是事务修改的数据,二级和三级是事务读取的数据
3,三级封锁协议及分别解决的问题
(1)一级:
a.内容:事务T在修改数据对象A之前必须对其加X锁,直到事务结束才释放。
b.可解决的问题:“丢失修改”问题
|
T1 |
T2 |
解释 |
|
① Xlock A |
|
事务T1在读A进行修改之前先对A加X锁 |
|
② R(A)=16 |
|
|
|
|
Xlock A |
当T2再请求对A加X锁时被拒绝 |
|
③ A←A-1 |
等待 |
T2只能等待T1释放A上的锁后T2获得对A的X锁
|
|
W(A)=15 |
等待 |
|
|
Commit |
等待 |
|
|
Unlock A |
等待 |
|
|
④ |
获得Xlock A |
|
|
|
R(A)=15 |
这时T2读到的A已经是T1更新过的值15 |
|
|
A←A-1 |
T2按此新的A值进行运算,并将结果值A=14送回到磁盘。避免了丢失T1的更新。 |
|
⑤ |
W(A)=14 |
|
|
|
Commit |
|
|
|
Unlock A |
|
思考:一级封锁协议为什么不能解决丢失修改和不可重复读问题?
在一级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不读“脏”数据。即,事务1对R加了排他锁,对数据R进行了修改,若事事务2对R申请锁,则会wait;若事务2不对R申请任何锁,则即使事务1对R加了排他锁,事务2也会无视,可以读!所以不能解决丢失修改和不可重复读问题
(2)二级:
a.内容:在一级封锁协议的基础上,另外加上事务T在读取数据对象A之前必须对其加S锁,读完后立即释放。
b.可以解决的问题:“丢失修改”、“读脏数据”问题
|
T1 |
T2 |
解释 |
|
① Xlock C |
|
事务T1在对C进行修改之前,先对C加X锁,修改其值后写回磁盘
|
|
R(C)=100 |
|
|
|
C←C*2 |
|
|
|
W(C)=200 |
|
|
|
② |
Slock C |
T2请求在C上加S锁,因T1已在C上加了X锁,T2只能等待
|
|
|
等待 |
|
|
③ROLLBACK |
等待 |
|
|
(C恢复为100) |
等待 |
T1因某种原因被撤销,C恢复为原值100
|
|
Unlock C |
等待 |
|
|
④ |
获得Slock C |
|
|
|
R(C)=100 |
T1释放C上的X锁后T2获得C上的S锁,读C=100。避免了T2读“脏”数据
|
|
⑤ |
Commit C |
|
|
|
Unlock C |
|
思考:为什么二级封锁不能解决“不可重复读”问题?
——事务1读取数据时加上共享锁后(这样在事务1读取数据的过程中,其他事务就不会修改该数据),
不允许任何事物操作该数据,只能读取,之后1如果有更新操作,那么会转换为排他锁,其他事务更无权参与进来读写,
这样就防止了脏读问题。但是当事务1读取数据过程中,有可能其他事务(例如事务2)也读取了该数据,事务1读取完毕后共享锁释放(此时事务1还未完),
此时事务2修改数据,修改完毕提交事务,那么事务1再次读取数据时候发现数据不一致,就会出现不可重复读问题,
所以这样不能够避免不可重复读问题。
(3)三级:
a.内容:在一级封锁协议的基础上,另外加上事务T在读取数据对象A之前必须对其加S锁,直到事务结束才释放。
b.可以解决的问题:“丢失修改”、“读脏数据”、“不可重复读”问题
|
T1 |
T2 |
解释 |
|
|
事务T1在读A,B之前,先对A,B加S锁; 其他事务只能再对A,B加S锁,而不能加X锁,即其他事务只能读A,B,而不能修改
|
|
Slock B |
|
|
|
R(A)=50 |
|
|
|
R(B)=100 |
|
|
|
求和=150 |
|
|
|
② |
Xlock B |
当T2为修改B而申请对B的X锁时被拒绝只能等待T1释放B上的锁
T1为验算再读A,B,这时读出的B仍是100,求和结果仍为150,即可重复读
T1结束才释放A,B上的S锁。T2才获得对B的X锁 |
|
|
等待 |
|
|
|
等待 |
|
|
③ R(A)=50 |
等待 |
|
|
R(B)=100 |
等待 |
|
|
求和=150 |
等待 |
|
|
Commit |
等待 |
|
|
Unlock A |
等待 |
|
|
Unlock B |
等待 |
|
|
④ |
获得XlockB |
|
|
|
R(B)=100 |
|
|
|
B←B*2 |
|
|
⑤ |
W(B)=200 |
|
|
|
Commit |
|
|
|
Unlock B |
|
注:关注点在哪里?
—— 一级封锁协议的关注点是事务修改的数据,二级和三级是事务读取的数据
4,总结:
(1)锁的相容矩阵:
(如果R上加了X锁后,就不能再加任何锁!如果R上加了S锁后,只能再加S锁而不能再加X锁!)
(2)
|
|
X锁 |
S锁 |
|
无丢失修改 |
无污读 |
可更新 |
|
|
事务结束释放 |
事务结束释放 |
读完释放 |
|
|
|
|
一级封锁协议 |
√ |
|
|
√ |
|
|
|
二级封锁协议 |
√ |
|
√ |
√ |
√ |
|
|
三级封锁协议 |
√ |
√ |
|
√ |
√ |
√ |
本文详细介绍了数据库并发控制中的封锁概念,包括排他锁和共享锁的使用及其作用,并深入解析了一级、二级和三级封锁协议的工作原理及各自解决的问题。
279

被折叠的 条评论
为什么被折叠?



