我终于搞懂了数据库锁封锁协议

这里只是介绍封锁协议,因为其他的其实不算很难理解,网上优秀的博客有很多。

在运用X锁和S锁这两种基本封锁对数据对象加锁时,还需要约定一些规则。例如,何时申请X锁或S锁、持锁时间、何时释放等。这些规则称为封锁协议。通常使用三级封锁协议来在不同程度上解决并发操作的不正确调度带来的更新丢失、不可重复读和读“脏”数据等不一致性问题,这就是封锁协议

一级封锁协议
一级封锁协议是指,事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。一级封锁协议可以防止丢失修改,因为一个事务修改的时候会上x锁,其他事务不能进行修改,但是此时其他事务进行读取的时候并不会去竞争锁,所以能直接读取,就造成了脏读

二级封锁协议
二级封锁协议是指,在一级封锁协议基础上增加事务T在读数据R之前必须先对其加S锁,读完后即可释放S锁(无需等待事务结束)。二级封锁协议出防止了丢失修改,还可以进一步防止读“脏”数据。因为此时T事务在修改数据上了X锁,T1事务想要读取的时候必须要上S锁,就需要等待了。

三级封锁协议
三级封锁协议是指,在一级封锁协议的基础上增加事务T在读数据R之前必须先对其加S锁,直到事务结束才释放。三级封锁协议出防止了丢失修改和读“脏”数据外,还可以进一步防止了不可重复读。

理解

1)第一个协议的意思就是,规定一个事务,如果当前事务打算修改这个数据R,就必须先对其加X锁,要想修改数据,就要先读取数据,读取之前就要加上X锁。什么?你问为什么要读数据?不读数据的话怎么会存在更新丢失问题,那就是直接覆盖了。

丢失修改:两个事务T1和T2同时读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改被丢失。

这样是解决了更新丢失问题,为什么解决了?因为我们要求如果一个事务想要去修改数据,读数据之前要将上x锁,所以如果两个事务都要去修改的话,前一个在读的时候加上了锁,另外一个事物在读取的时候也需要加锁,但是X锁只能上一个,他就只能等了,所以就解决了更新丢失问题

2)第二个协议又加上了一个限制,如果有个事务想要读取数据,必须要先加S锁,我开始就很疑惑,我一个事务都加上了X锁了,加个S锁干什么,这其实是我走进了一个误区,我一直以为这是针对的同一个事务而言。
首先我们要知道,在一级协议中,我们只规定了写数据时加的锁,并没有规定读数据需不需要加锁。所以说,如果我一个事务A正在修改数据,加上了X锁,然后另外一个事务B打算来读取数据,他不需要去加锁,也就不存在竞争问题,所以,他能够读取到A事务没有提交的数据,导致了脏读。说到这我想你应该大概明白了其中的含义了吧,二级协议就是在一级协议的基础上规定,你一个事务要读取数据之前,必须要加S锁,如果另外一个事务正在写,就会导致当前读事务被阻塞了,也就解决了脏读问题。

3)三级协议同样是补充了二级协议,二级协议在一个事务中可能会多次获取和释放S锁,这就导致了可能在一个事务中多次获取的数据不一样,这就是不可重复读。因为我这个读事务一直在事务中,讲道理应该每次获取到的数据都是一样的,但是因为二级协议规定的是读取完之后马上释放锁,就导致了这个问题。所以三级协议规定,在整个事务中都要加上S锁,所以想要进行修改的事务就不能正常的加上X锁,然后修改数据,所以读锁读到的数据始终是一样的。

发布了180 篇原创文章 · 获赞 49 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/P19777/article/details/104813937