使用封锁协议解决事务的并发问题

时间:2022-07-22
本文章向大家介绍使用封锁协议解决事务的并发问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、事务的并发问题


事务是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。

并发是指多个事务同时执行,这会带来一些问题。

丢失修改

丢失修改由两次事务的修改导致,比如事务 T1 修改 A,同时事务 T2 也修改 A,那么最后 A 的值将由事务 T2 的修改结果决定,这样事务 T1 的修改就没了,导致丢失修改。

不可重复读

分为两种情况,第一种是事务 T1 读取 K ,这个时候读取到一个值 A,然后事务 T2 增加或者删除了一条记录,过了一会事务 T1 又过来读取了这个 A ,发现值不见了,或者多了一些值,很迷幻,所以叫幻读。

第二种情况就是前面相同,但是事务 T2 修改了刚才读取的那个值 A ,导致事务 T1 再过来读的时候发现值不一样了,这叫做不可重复读。

脏读

事务 T1 修改了 A 的值,但是还没有提交,这个时候被事务 T2 读取了 A 的值,但是过了一会事务 T1 由于某些原因回滚了操作,所以 T2 读取到的值就是错的,这就是 脏读

二、封锁协议


两类锁

两类锁分别是 排它锁 X共享锁 S

T 给数据 A 加上排它锁之后,就只有 T 才能读和修改 A,同时其他事务就不能再加任何锁了,直到 T 释放排它锁。

T 给数据 A 加上共享锁之后,T 只能读 A,不能修改,其他事务可以在它的基础上加共享锁,但是不能加排它锁,也就是说其他的事务只能读不能修改,直到 T 释放共享锁为止。

封锁协议

封锁协议规定了使用锁对数据对象加锁时需要遵循的规则。

一级封锁协议

它规定事务在修改数据之前必须加排它锁,直到事务结束才释放。

这就解决了丢失修改的问题,因为事务在修改数据的时候要加 X 锁,之后其它事务就不能再加锁了,也就是不能修改了,必须等第一个事务修改完成之后才能再加锁然后修改。

但是读数据的时候是不用加锁的,那就解决不了其它的问题。

二级封锁协议

它规定事务在读取事务之前必须加共享锁,而 读取结束就释放

注意这里是读完了就可以释放锁了,还是不太行,但是可以解决脏读的问题:比如事务 T1 在修改数据的时候加了 X 锁,这个时候事务 T2 要想再读取就要加 S 锁,但是在 X 锁释放之前是不能加其他锁的,所以必须等待事务 T1 释放锁,这个时候无论他是提交事务还是回滚都不会影响到 T2 读取的数据正确性了。

但是他不能不解决可重复读的问题。

三级封锁协议

它规定事务在读取事务之前必须加共享锁,直到 事务结束 才释放。

这就解决了不可重复度的问题,因为当事务 T1 读取数据对象的时候,加了 S 锁,其他的事务想修改该数据对象,必须加 X 锁,但是在 S 锁之上是不能加 X 锁的,只能等到 T1 释放 S 锁,而释放的时候事务 T1 也结束了。