数据库4种隔离级别与3级封锁协议


数据库并发会引发的问题

  • 脏读(dirty read):A事务读取B事务尚未提交的更改数据,并在这个数据基础上操作。如果B事务回滚,那么A事务读到的数据根本不是合法的,称为脏读。在oracle中,由于有version控制,不会出现脏读
  • 不可重复读(unrepeatable read):A事务读取了B事务已经提交的更改(或删除)数据。比如A事务第一次读取数据,然后B事务更改该数据并提交,A事务再次读取数据,两次读取的数据不一样
  • 幻读(phantom read):A事务读取了B事务已经提交的新增数据。注意和不可重复读的区别,这里是新增,不可重复读是更改(或删除)。这两种情况对策是不一样的,对于不可重复读,只需要采取行级锁防止该记录数据被更改或删除,然而对于幻读必须加表级锁,防止在这个表中新增一条数据
  • 第一类丢失更新:A事务撤销时,把已提交的B事务的数据覆盖掉
  • 第二类丢失更新:A事务提交时,把已提交的B事务的数据覆盖掉

读未提交

最低隔离级别,允许一个事务能够读到另一个事务未提交的信息,只对修改数据的并发操作做限制(对于数据而言,写之前加X锁,直到事务结束释放X锁,对应一级封锁协议),这样解决了第一类丢失更新的问题,虽然一个事务不能修改其他事务正在修改的数据,但是可以读到其他事务还未提交的修改,如果这些修改未提交,那么就会成为脏数据,所以还未解决脏读的问题,自然,就算是已经提交的数据,多次读取结果也不一定一样,所以还未解决不可重复读幻读的问题(存在的问题:脏读,不可重复读,幻读

读已提交

只能读取已经提交的数据,换句话说,就是一个事务读取其他事务中正在修改的数据是不被允许的(一级封锁协议+读之前加S锁,读完数据释放S锁,对应二级封锁协议),由于读完之后就释放S锁,所以不能保证不可重复读幻读

可重复读

读已提交下,同一事务内,允许多次相同的查询能够得到不同的结果,可以使用二级封锁协议+MVCC使得当前事务只能读取不高于其事务版本的数据,也可以使用三级封锁协议(一级封锁协议+读之前加S锁,直到事务结束释放S锁)能解决可重复读,同时也解决了幻读

可串行化

可重复读与幻读的区别是:可重复读是更改表中行级数据,而幻读是增加表中行级数据,幻读可以通过三级封锁协议消除,可串行化使得所有的事务必须串行化执行,解决了一切并发问题,但会造成大量的等待、阻塞甚至死锁,使系统性能降低

参考

MySQL隔离级别和封锁协议


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com