第八章——并发控制

首先区分交叉并发方式和同时并发方式。

8.1,并发控制概述

并发带来的三种数据不一致性:1,丢失修改;2,不可重复读(又可分三种具体情况,后两种称为幻影现象);3,读脏数据。


8.2,封锁

两种锁:排它锁(X锁)和共享锁(S锁)。

排它锁称为写锁,即只有加锁的事务可以对其读取和修改,其他事务不能对其加任何锁,即既不能读也不能写;共享锁称为读锁,当某事务对数据加S锁,则其他事物可以对其加S锁,一切共享读数据。


8.3,封锁协议

一级封锁协议

当事务T对数据R修改之前必须对其加X锁,直到操作完毕。

一级封锁协议中,若只读数据不写数据是不需要加锁的,所以不能解决不可重复读和脏数据。

二级封锁协议

在一级协议之上,加上当事务T读取数据R时,必须加上S锁,读取后释放S锁。

这能解决脏数据问题,但是不能解决可重复读。

三级封锁协议

在一级协议之上,加上当事务T读取数据R时,必须加上S锁,事务结束后才能释放。

这就可以重复读了。


8.4,活锁和死锁

活锁

本来可以得到锁,但是被插队了,导致一直得不到锁。通过先来先服务的原则可以解决活锁问题。

死锁

死锁产生的原因

事务T1首先拿到了A锁,事务T2首先拿到了B锁,T1过了一会需要B锁,于是等待T2释放B锁,但是T2过了一会需要A锁,于是等待T1释放A锁,这就导致两方永无止境的等待下去。

通过两种方法来解决死锁问题,死锁预防和死锁检测解除。

死锁预防

一次封锁法:事务必须一开始就取得全部需要的锁。这会导致并发度降低。

顺序封锁法:建立B树来确定正确的拿锁顺序,但是很困难,成本很高。

死锁检测解除

超时法:如果事务运行超过预期时间,则可认为死锁,上去解除。问题是有可能误判,同时如果预期时间设置过长,会导致不能及时发现。

等待图法:建立有向图,节点为事务,边为等待情况。周期性检测是否有回路,有则说明死锁。


8.5,并发调度的可串行性

多个事务的并发执行是正确的,当且仅当其结果与按某一次序顺序执行的结果相同时,则称为可串行化。

一个给定的并发调度,当且仅当是可串行化时,才是正确调度。

通过二段所来保证事务的正确调度。


8.6,二段锁协议

事务对锁的操作分为两个阶段:扩展阶段(拿锁阶段)和收缩阶段(放锁阶段)。

扩展阶段只能拿锁不能放锁,收缩阶段只能放锁不能拿锁。

二段锁协议保证可串行化,但是可串行化不一定都是二段锁协议。

二段锁协议和一次封锁法有区别,一次封锁法是在开头拿所有锁,而二段锁协议是在一个阶段渐进的拿锁,这意味着二段锁协议可能导致死锁。

8.7,封锁的粒度

就是封锁对象的大小,是元组,还是数据项,还是整个表或者更大的。

粒度越大,并发度越低,系统开销越小;粒度越小,并发度越高,开销越大。

多粒度封锁

为了灵活处理,系统如果支持不同粒度供事务选择,则成为多粒度封锁。

根据层次关系建立粒度树,在粒度树种某一节点加的锁称为显示封锁,该锁会扩散到其所有子孙节点,称为隐式封锁。

显然这种显隐式封锁在每次加锁前要增加许多检查,故效率较低。

意向锁

在对任一节点加锁时,必须先对其上层节点加意向锁。

三种意向锁:意向共享锁(IS锁)、意向排它锁(IX锁)、共享意向排它锁(SIX锁)。

IS锁:某节点加IS锁,则其后裔“意向”加S锁,这里意向可以理解为打算。

IX锁,某节点加IX锁,则其后裔“意向”加X锁。

SIX锁:某节点加SIX锁,则该节点加S锁,然后再加IX锁,则其后裔意向加X锁。

你可能感兴趣的:(第八章——并发控制)