第8章 并发控制
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
17
串行调度
时间 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 事务T1 Slock(B) 读B=2 Unlock(B) Xlock(A) A=B+1=3 写回A=3 Commit Unlock(A) Slock(A) 读A=3 Unlock(A) 事务T2 时间 1 2 3 4 5 6 7 8 9 10 11 Xlock(B) B=A+1=4 写回B=4 Commit Unlock(B)
二级封锁协议:一级封锁协议加上事务T在读取数据A前必须先 对其加S锁,读完后立即释放S锁(防丢失修改,防读“脏”数 据)。
三级封锁协议:一级封锁协议加上事务T在读取数据A前必须先 对其加S锁,直到该事务结束才释放S锁(防丢失修改,防读“ 脏”数据,防不可重复读)。
9
一级封锁协议的并发调度
时间 1 2 3 4 A=A-1 事务T1 Xlock (A) 读A=16 Xlock (A)等待 事务T2 数据库中A的值 16
在释放一个封锁之后,事务不再申请和获得任何其他封锁。
两段的含义
扩展阶段:只获得锁,不释放锁。 收缩阶段:只释放锁,不获得锁。 遵守2PL协议是可串行化调度的充分条件,但不是必要条件。
20
遵守及不遵守2PL并发调度示例
时间 1 2 3 4 5 事务T1 Slock(B) 读B=2 Xlock(A) A=B+1=3 Slock(A)等待 事务T2 时间 1 事务T1 Slock(B) 读B=2 Unlock(B) Xlock(A) Slock(A)等待 事务T2
并发操作:多个用户同时对某个数据库对象进行的操作。若对 并发操作不加控制就可能存取不正确数据,破坏数据库的一致 性。所以DBMS必须提供并发控制机制,对并发操作进行正确 调度、保证事务的隔离性、保证数据库的一致性,它是衡量一 个DBMS性能的重要标志之一。
3
并发操作可能引起的三类数据不一致问题 丢失修改:指两个事务T1和T2从数据库中读入同一数据并修 改,T2的提交结果破坏了T1提交的结果,导致T1的修改被丢失
4
5 6 7 8 …
Unlock(A)
……
…… …… …… ……
……
Unlock(A)
……
Xlock(A) …… Unlock(A)
…
… … … … … …
活锁的避免:采用“先来先服务”策略。
14
死锁:多个事务同时处于等待状态,每个事务都在等待其它 事务释放锁使其能够继续执行,从而出现多个事务互相等待的 僵局,每个事务永远不能结束。
数据库基础与应用
第三章 关系数据库规划和设计(继)
----并发控制
1
学习目标
理解三类数据不一致问题 理解封锁的概念和三级封锁协议 理解活锁和死锁 掌握并发调度的可串行性 掌握2PL协议 理解封锁的粒度 掌握SQL Server的并发控制技术
2
3.3.3.1 并发控制概述
数据库是一个共享资源,允许多个用户同时访问。多用户数据 库系统中多事务的执行方式有:
事务遵守2PL协议
2 3 4
事务不遵守2PL协议
5
6
A=B+1=3
写回A=3 Commit …… ……
6
7 8 9 10 11
写回A=3
Commit Unlock(A,B)
……
…… …… Slock(A) 读A=3 Xlock(B)
7 8
9
10 11 12 13
Unlock(A)
……
Slock(A) 读A=3 Unlock(A) Xlock(B)
……
5
6 7 8 9 10 11 12 13
写回A=15
Commit Unlock(A)
一级封锁协议解决了丢失修改。 …… 但如果T2首先读A,T1修改A(减 1)提交后,T2再读A则出现不可 …… 重复读问题;如果T2在第5步后 Xlock (A) 读A,然后T1执行Rollback,则 14 读A=15 T2读了“脏”数据。
时间 1 2 3 4 5 6 A=A-1 写回A=15 Commit A=A-1 15 事务T1 读A=16 读A=16 最后的结果错误!原 因是T2执行第7步后丢 失了T1对A的更新。 事务T2 数据库中A的值 16
7
8
写回A=15
Commit
4
15
不可重复读:不可重复读是指事务T1读取数据后,事务T2执 行更新操作,使T1无法再现前一次读取结果。
时间
1 2 3
事务T1
Xlock(A) Xlock(B)等待 ……
事务T2
Xlock(B) Xlock(A)等待 ……
4
死锁的预防 一次封锁法:要求每个事务必须一次将所有要使用的数据全 部加锁,否则就不能继续执行。它存在两个问题:一是扩大了封 锁范围;二是很难事先精确确定每个事务所要封锁的数据对象, 只能将事务执行中可能要封锁的数据对象全部加锁,降低了并发 度
串行执行:每个时刻只有一个事务运行,其他事务必须等到该 事务结束后才能运行,它不能发挥数据库共享资源的特点。
交叉并发方式:事务并行操作,轮流交叉运行,这是单处理机 系统的并发方式,能够减少CPU空闲时间,提高系统的效率。 同时并发方式:多处理机系统中,每个处理机可以运行一个事 务,多个处理机可以同时运行多个事务,实现多个事务真正的 并行运行。这是最理想的并发方式,但受制于硬件环境。
T1 T2
X锁 S锁 -
X锁 N N Y
S锁 N Y Y
8
- Y Y Y
X锁和S锁的相容性 Y为相容,N为不相容。 若两个锁不相容,则后提 出锁请求的事务必须等待
3.3.3.3 封锁协议
封锁协议:事务对数据封锁时,何时申请X锁或S锁、持锁时间 、何时释放等有关封锁的规则。 一级封锁协议:事务T在修改数据A之前必须先对其加X锁,直 到该事务结束才释放X锁。 (防丢失修改)
7
8 9 10 11 12 13 14 15 16
Commit
Unlock(A)
Commit
Unlock(B)
结果A=3、B=3,是不可串行化调度
19
3.3.3.6 两段锁协议
两段锁协议(Two Phase Locking,2PL)
事务在对任何数据进行读、写之前,首先要申请并获得该数据 上的封锁。
6
读“脏”数据:事务T1修改某一数据,并将其写回磁盘,事 务T2读取同一数据后,T1由于某种原因被撤消,这时事务1已修 改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致 ,则T2读到的数据称为“脏”数据。
时间 1 2 3 事务T1 读C=100 C=C*2 写回C=200 200 最后的结果错误!原因是 T1在第6步取消了对C的更 新,但T2仍使用取消前的 C值,读了“脏”数据。 100
50、200
8
9 10 11
Unlock(A,B)
……
Xlock(B) 读B=100 B=B*2
12
13
写回B=200
Commit 12
封锁协议小结
13
3.3.3.4 活锁与死锁
活锁:某个事务永远处于等待封锁的状态。
时间 1 2 3 事务T1 Xlock(A) …… …… 事务T2 Xlock(A)等待 …… …… 事务T3 Xlock(A)等待 …… Xlock(A) 事务T4 Xlock(A)等待 …… …… … … … …
10
11
Commit
Unlock(C)
11
三级封锁协议的并发调度
时间 1 事务T1 Slock (A,B) 事务T2 数据库中A、B的值 50、100
wk.baidu.com
2
3 4 5 6 7
读A=50,B=100
求和150 Xlock(B)等待 读A=50,B=100 求和150 Commit
…… ……
……
三级封锁协议解决了丢失 修改、不可重复读和读“ 脏”数据问题。
死锁的诊断与解除 诊断:DBMS一般使用超时法或事务等待图法。 解除:死锁发生后DBMS选择处理代价最小的事务将其回滚,并 释放它所持有的所有锁。
16
3.3.3.5 并发调度的可串行性
可串行化调度:若多个事务并发调度的结果与任一串行调度的 结果相同,则该并发调度是可串行化调度,两段锁协议是保证 并发调度可串行性的封锁协议。 对于一个给定的并发调度,当且仅当它是可串行化的,才认为 是正确的调度。例:设A、B的初值都是2,现有两个事务: 事务T1:读B;A=B+1;写回A。 事务T2:读A;B=A+1;写回B。
Unlock(A)
可串行化调度与不可串行化调度
结果A=3、B=4,是可串行化调度
时间
1 2 3 4 5 6
事务T1
Slock(B) 读B=2 Unlock(B) Xlock(A) A=B+1=3 写回A=3
事务T2
Slock(A) 读A=2 Unlock(A) Xlock(B) B=A+1=3 写回B=3
15
顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务都 按这个顺序实行封锁。它也存在两个问题:一是数据库系统中 可封锁的数据对象极多并且不断变化,要维护这些资源的封锁 顺序非常困难;二是事务的封锁请求可以随着事务的执行而动 态地决定,很难事先确定每一个事务要封锁哪些对象,也就很 难按规定的顺序去施加封锁。如规定数据对象的封锁顺序为 A,B,C,D,E。事务T3起初要求封锁数据对象B,C,E,但当它封 锁了B,C后,才发现还需要封锁A,这样就破坏了封锁顺序。 因此DBMS解决死锁更普遍采用诊断+解除的方法。
事务T2
3
4 5 6 7
Xlock(A)等待
……
Slock(A)
读A=2 Xlock(B)等待 ……
A=A-1 写回A=14 Commit Unlock(A) 10
……
15
二级封锁协议的并发调度
时间 1 2 3 4 5 6 7 8 9 Rollback Unlock(C) 事务T1 Xlock (C) 读C=100 C=C*2 写回C=200 Slock (C)等待 …… …… Slock (C) 读C=100 100 二级封锁协议解决了丢 失修改和读“脏”数据 问题,但如果T2首先读C ,T1修改C(减1)提交后 ,T2再读C,则出现不可 重复读问题。 200 事务T2 数据库中C的值 100
12
13 14 15
B=A+1=4
写回B=4 Commit Unlock(A,B)
21
14
15 16 17
B=A+1=4
写回B=4 Commit Unlock(B)
2PL协议不同于一次性封锁:一次性封锁遵守2PL协议,但 遵守2PL协议的事务可能发生死锁。
时间
1 2
事务T1
Slock(B) 读B=2
7 7
事务T2
数据库中C的值 100
4
5 6 Rollback
读C=200
Commit
3.3.3.2 封锁
封锁:任何事务T在对某数据操作之前,先向系统发出请求 对其加锁。加锁后事务T就对该数据拥有了一定的控制权,在 事务T释放锁之前其它事务不能更新该数据。 排它锁(X锁,写 锁):若事务T对数据A加X锁,则只允许T读取和修改A,其他 事务不能再对A加任何锁,直到T释放A上的X锁。它保证了在T 释放A上X锁之前其他事务不能再读取和修改A 共享锁(S锁,读 锁):若事务T对数据A加S锁,则事务T只可读A,但不能修改A ,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的 S锁。它保证了在T释放A上S锁之前其它事务可以读A,但不能 修改A。
18
事务T1
事务T2 Slock(A) 读A=2 Unlock(A)
Slock(B)
Xlock(B) B=A+1=3 写回B=3 Commit Unlock(B)
结果A=3,B=4
读B=3 Unlock(B) Xlock(A) A=B+1=4 写回A=4
结果A=4,B=3
12 13 14
15
16
Commit
时间 事务T1 事务T2 数据库中A、B的值
1
2 3 4 5
读A=50,B=100
求和150 读B=100 B=B*2 写回B=200
50、100
50、200
6
7 8 9
读A=50,B=200
求和250 Commit
Commit T1无法再现第2步读到 的结果!原因是T2在 第5步对B的修改。
5
不可重复读包括三种情况: 事务T1读取某一数据后,事务T2对其做了修改,当T1再次读 该数据时,得到与前一次不同的值。 事务T1按一定条件从数据库中读取了某些数据记录后,事务T2 删除了其中部分记录,当T1再次按相同条件读取数据时,发现 某些记录神密地消失了。 事务T1按一定条件从数据库中读取了某些数据记录后,事务T2 插入了一些记录,当T1再次按相同条件读取数据时,发现多了 一些记录。 后两种情况也称为幻影现象(Phantom Row)。