三级封锁协议实例

在网上看了很多三级封锁协议的例子,大部分都是不正确的(例如T1加了X锁后,T2还加S锁)。以下是正确的实例。
首先描述一下三级封锁协议。
一级封锁:要写数据,写前加X锁,事务结束才释放。
二级封锁:在一级封锁的基础上,要读数据,读前加S锁,读后释放。
三级封锁:在一级封锁的基础上,要读数据,读前加S锁,事务结束才释放。
一级封锁可以解决丢失修改问题,二级封锁可以再解决读脏数据问题,三级封锁可以再解决不可重复读问题。
一级封锁协议作用实例
不加封锁的情况:
| T1 | A的值 | T2 |
| Read(A) | 100 | |
| 100 | Read(A) | |
| A=A-10 | ||
| Write(A) | 90 | |
| A=A-20 | ||
| 80 | Write(A) |
在上述实例中,T1对A减10,T2对A减20,如果串行执行,A应该减了30,也就是最后结果是70。但上述实例的运行结果是80,出现了丢失修改的问题。
由于T1和T2都需要对A进行写,所以按照一级封锁协议,实际运行应该是:
| T1 | A的值 | T2 |
| XLock(A) | ||
| Read(A) | 100 | |
| A-A-10 | 由于加了X锁,无法再加X锁,只能等待 | |
| Write(A) | 90 | 等待 |
| Unlock(A) | 等待 | |
| XLock(A) | ||
| 90 | Read(A) | |
| A=A-20 | ||
| 70 | Write(A) | |
| Unlock(A) |
上述实例运行之后,结果就是正确的,解决了丢失修改的问题。
二级封锁协议作用示例
只遵循一级封锁协议的情况:
| T1 | A的值 | T2 |
| XLock(A) | ||
| Read(A) | 100 | |
| A=A-10 | ||
| Write(A) | 90 | |
| 90 | Read(A) | |
| Rollback | 100 | |
| Unlock(A) |
在上述实例子,T1执行结束后,A的值是100,而T2读到的值是90。这产生了读脏数据的问题。
按照二级封锁协议,T2在读数据前,必须加上S锁,结果如下:
| T1 | A的值 | T2 |
| XLock(A) | ||
| Read(A) | 100 | |
| A=A-10 | ||
| Write(A) | 90 | |
| Rollback | 100 | 由于加了X锁,无法再加S锁,只能等待 |
| Unlock(A) | 等待 | |
| SLock(A) | ||
| 100 | Read(A) | |
| Unlock(A) |
可以看到,二级封锁协议解决了读脏数据的问题。
三级封锁协议作用示例
遵循二级封锁协议的情况:
| T1 | A的值 | T2 |
| SLock(A) | ||
| Read(A) | 100 | |
| Unlock(A) | ||
| XLock(A) | ||
| 100 | Read(A) | |
| A=A-10 | ||
| 90 | Write(A) | |
| Unlock(A) | ||
| SLock(A) | ||
| Read(A) | 90 | |
| Unlock(A) |
在上述例子中,T1第一次读A是100,第一次读是90,出现了不可重复读的问题。
按照三级封锁协议,T1在事务结束前才能释放S锁,结果如下:
| T1 | A的值 | T2 |
| SLock(A) | ||
| Read(A) | 100 | |
| Read(A) | 100 | 由于加了S锁,不能再加X锁,只能等待 |
| Unlock(A) | 等待 | |
| XLock(A) | ||
| 100 | Read(A) | |
| A=A-10 | ||
| 90 | Write(A) | |
| Unlock(A) |
可以看到,三级封锁协议解决了不可重复读的问题。


