数据库隔离级别解决脏读、不可重复读、幻读

一、脏读、不可重复读、幻读

  1. 脏读
    读取了未提交的事务。
    事务A读取了事务B中尚未提交的数据。如果事务B回滚,则A读取使用了错误的数据。
    解决:如果一个事务在读的时候,禁止读取未提交的事务。

  2. 不可重复读
    读取了提交的新事物,指更新操作。
    期望两次读的结果一样,但中途另一个事务修改了数据并提交了,导致第二次读的结果变了。
    解决:如果一个事务在读的时候,禁止任何事务写。

  3. 幻读
    也是读取了提交的新事物,指增删操作。
    不可重复是针对记录的update操作,只要在记录上加写锁,就可避免;幻读是对记录的insert操作,禁止幻读必须加上全局的写锁。比如在表上加写锁。

    例:
	事务A,先执行:
	update table set name="hky" where id > 3

	事务B,后执行,并且提交:
	insert into table values(11, 'uu')

	事务A,再select一下:
	select * from table where id > 3
 	结果集:11,uu
	
	事务A懵了,我tm刚更新完id>3的啊?!幻觉?!

由此,也可以看出不可重复读和幻读区别,不可重复读操作是本身记录读取产生的,幻读则是一个范围。

二、事务隔离级别

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读这几类问题。
在这里插入图片描述

  • Read uncommitted(读未提交)
    最低的隔离级别。一个事务可以读取另一个事务并未提交的更新结果。也就是会出现脏读。

  • Read Committed(读提交)
    大部分数据库采用的默认隔离级别。如oracle,写操作加写锁,读操作加读锁。
    一个事务的更新操作结果只有在该事务提交之后,另一个事务才可以的读取到同一笔数据更新后的结果。
    也就是一个事务开始读了,另一个事务开始写,读只能读到另个事务未提交之前的数据。

  • Repeatable Read(重复读)
    mysql的默认级别
    整个事务过程中,对同一批数据的读取结果是相同的,不管其他事务是否在对共享数据进行更新,也不管更新提交与否。

    这里涉及到一个问题,例如mysql,那innoDB是怎么解决幻读的?
    mysql默认级别RR下,innoDB使用MVCC和next-key locks解决幻读。MVCC解决的是普通读(快速读)的幻读,next-key locks解决的是当前读情况下的幻读。

    (1) 当前读:
    所谓当前读,是指加锁的select,update,delete等语句。在RR事务隔离级别下,数据库会使用next-key locks来锁住本条记录及索引区间。
    以上述幻读的例子来说,在RR情况下,假设使用的是当前读,加锁了读select * from table where id>3 ,锁住的就是id=3这条记录及id>3这条区间范围,锁住索引记录之间的范围,避免范围内插入记录,避免产生幻读行记录。

    (2) 普通读:
    普通读是不加锁的读,解决幻读的手段是MVCC。
    MVCC会给每行元组加一些辅助字段,记录创建版本号和删除版本号。
    而每个事务在启动的时候,都有一个唯一的递增的版本号。开启新事务,事务版本号就会递增。

    • SELCT
      读取创建版本小于或等于当前事务版本号,并且删除版本为空或大于当前事务版本号的记录。这样就可以保证在读取之前记录是存在的。
    • INSERT
      将当前事务的版本号保存至行的创建版本号
    • UPDATE
      新插入一行,并以当前事务的版本号作为新行的创建版本号,同时将原记录行的删除版本号设置为当前事务版本号。
    • DELETE
      将当前事务的版本号保存至行的删除版本号

    具体参考链接:
    https://mp.weixin.qq.com/s/GoJIYQqqiNBamFnwiFoRXw
    https://www.cnblogs.com/wudanyang/p/10655180.html

  1. Serializable(序列化)
    最高隔离级别。所有事务操作依次顺序执行。注意这会导致并发度下降,性能最差。通常会用其他并发级别加上相应的并发锁机制来取代它。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值