封锁
11.2.1 什么是封锁
封锁就是事务T在对某个数据对象(例如表、记录)操作之前,先向系统发出请求,对其加锁
加锁后事务T就对该数据对象又一定的控制,在事务T释放他的锁之前,其他事务不能更新此数据对象
封锁是实现并发控制的一个非常重要的技术
一个事务对某个数据对象加锁后拥有怎样的控制由封锁的类型来决定
基本封锁类型
排他锁(X锁)
共享锁(S锁)
1.排他锁(X锁)
若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事物都不能再对A加任何类型的锁,直到T释放A上的锁
保证其他事物再T释放A上的锁之前不能再读取和修改A
写锁
2.共享锁(S锁)
若事物T对数据对象加了S锁,则事物T可以读A但不能更改A,其他失去只能再对A加S锁,而不能加X锁,直到T释放A上的S锁
保证其他事物可以读A,但在T释放A上 的S锁之前不能对A做任何修改
读锁
11.3 封锁协议
在运用X锁和S锁对数据对象加锁时,需要约定一些规则,这些规则未封锁协议
何时申请X锁和S锁
持锁时间
何时释放
对封锁方式规定不同的规则,就形成了各种不同的封锁协议,在不同的程度上保证并发操作的正确调度
三级封锁协议
一级封锁协议
二级封锁协议
三级封锁协议
1.一级封锁协议
事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放
正常结束(COMMIT)
非正常结束(ROLLBACK)
一级封锁协议可以防止丢失数据,并保证事务T是可恢复的
在一级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不读“脏”数据
2. 二级封锁协议
一级封锁协议加上事务T在读取R之前先对其加S锁,读完后即可释放S锁
二级封锁协议可以防止丢失修改和“脏”数据
使用二级封锁协议不能解决不可重复读
3. 三级封锁协议
一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放
三级封锁协议可以防止丢失修改,读“脏”数据和不可重复读
4.为什么二级封锁协议可以解决脏读?
前面我们说过脏读产生的原因:因为B事务读取到了A事务修改过尚未提交的数据,根据二级封锁协议要求:读数据的时候必须加S锁,但因为A事务在修改的时候已经加了X锁,在X锁的基础上是不能加S锁的,所以B事务无法获取S锁,就会导致B事务无法读取A事务中正在操作的数据,从而避免了脏读的发生。
5.为什么三级封锁协议可以解决不可重复读?
前面我们也说过了不可重复读产生的原因:是因为B事务读取到了A事务已经修改过的数据,导致前后两次读取的数据不一致。现根据三级封锁协议的要求:读取数据时必须加S锁,在S锁的基础上只能加S锁,不能加X锁,所以在B事务读取数据期间,A事务无法对数据进行修改,从而避免了不可重复读问题的发生。