疑惑
在学习三级封锁协议的时候非常疑惑,为什么一级封锁协议不能保证不读取到脏数据,相比大家也有同样疑惑,那就是一级封锁协议中事务对数据进行更新和读取时必须加上排他锁,既然加了排他锁,那么另一个事务就不能对该数据进行读取了,就不会存在脏读的情况了,那么真的对吗?大家应该被绝大多数书上所给的排他锁和共享锁的定义给迷惑了,我个人是不认同这个定义的,如下所示:
排他锁(X):也称为独占锁,它允许一个事务完全控制并修改数据对象,阻止其他事务同时访问该数据对象。排他锁主要用于修改数据,即对数据对象进行插入、删除和更新等操作。持有排他锁的事务可以独占数据对象,其他事务必须等待排他锁释放后才能对数据进行读取或修改。
共享锁(S):也称为读锁,它允许多个事务同时读取数据对象,但不能阻止其他事务获取共享锁。持有共享锁的事务可以允许其他事务读取数据对象,但不能修改它。共享锁主要用于读取数据,可以提高并发性能,减少锁竞争和系统负载。
其实真正决定数据对象本身能不能被某个事务读取或者更新,取决于如下这个锁的相容表
一级封锁协议:
一级封锁协议是:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放,对数据读取时候不加锁。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。一级封锁协议可以防止丢失修改(因为事务结束前都禁止其它事务进行数据修改),并保证事务T是可恢复的。
使用一级封锁协议可以解决丢失修改问题。那么首先事务A给数据加上了X锁,那么事务B要想更新修改数据,需要对数据进行上锁X锁,但是XX组合由上表可知,是不相容的,那么事务B不能修改,事务B要进行读取数据,不需要上锁,也就是X“-”组合,由上表可知,相容,于是事务B就能够读取数据,此时就可能产生脏读。
二级封锁协议
同样二级封锁协议也好理解了,同样是上面情景,此时如果事务B要读,将会是XS组合,那么是不相容的,那么事务B就不能在事务A未释放X锁前进行读取。从而解决了脏读问题。如果是这种情况呢
事务A先上S锁执行读取,读取到了M=50,之后立即释放了S锁,此时数据上没有锁,事务B可以对数据上锁X锁,形成X“-”组合,此时相容,事务B正常对数据进行修改,M=150,之后释放X锁,这时候数据上又没有锁了,事务A再对数据上S锁,读取到了M为150,出现了不可重复性读。
三级封锁协议,就这样分析吧