数据库的脏读、幻读、不可重复读以及四种隔离级别

脏读、幻读、不可重复读

脏读
也就是当数据库的一个事务A正在使用一个数据但还没有提交,另外一个事务B也访问到了这个数据,还使用了这个数据,这就会导致事务B使用了事务A没有提交之前的数据。

幻读
是指事务不独立执行产生的一种现象。事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。这样就会导致当A本来执行的结果包含B执行的结果,这两个本来是不相关的,对于A来说就相当于产生了“幻觉”。

不可重复读
在一个事务A中多次操作一个数据,在这两次或多次访问这个数据的中间,事务B也操作此数据,并使其值发生了改变,这就导致同一个事务A在两次操作这个数据的时候值不一样,这就是不可重复读。

数据库的四种隔离级别(并发事务)

(一)可读取未提交(Read uncommitted)

  • 顾名思义,就是可以读到未提交的内容。
    因此,在这种隔离级别下,查询是不会加锁的,也由于查询的不加锁,所以这种隔离级别的一致性是最差的,可能会产生“脏读”、“不可重复读”、“幻读”。
    如无特殊情况,基本是不会使用这种隔离级别的

  • 写事务阻止其他写事务,避免了更新遗失。但是没有阻止其他读事务。
    存在的问题:脏读。即读取到不正确的数据,因为另一个事务可能还没提交最终数据,这个读事务就读取了中途的数据,这个数据可能是不正确的。
    解决办法就是下面的“可读取确认”。

(二)可读已提交(Read committed)

  • 顾名思义,就是只能读到已经提交了的内容。
    这是各种系统中最常用的一种隔离级别,也是SQL
    Server和Oracle的默认隔离级别。这种隔离级别能够有效的避免脏读,但除非在查询中显示的加锁
  • Sql Server , Oracle的默认隔离级别 写事务会阻止其他读写事务。读事务不会阻止其他任何事务。 存在的问题:不可重复读。即在一次事务之间,进行了两次读取,但是结果不一样,可能第一次id为1的人叫“李三”,第二次读id为1的人就叫了“李四”。因为读取操作不会阻止其他事务。
    解决办法就是下面的“可重复读”。

(三)可重复读(Repeatable read)

  • 可重复读,顾名思义,就是专门针对“不可重复读”这种情况而制定的隔离级别,自然,它就可以有效的避免“不可重复读”。而它也是MySql的默认隔离级别。
    在这个级别下,普通的查询同样是使用的“快照读”,但是,和“读提交”不同的是,当事务启动时,就不允许进行“修改操作(Update)”了,而“不可重复读”恰恰是因为两次读取之间进行了数据的修改,因此,“可重复读”能够有效的避免“不可重复读”,但却避免不了“幻读”,因为幻读是由于“插入或者删除操作(Insertor Delete)”而产生的。

  • MySQL的默认隔离级别
    读事务会阻止其他写事务,但是不会阻止其他读事务。
    存在的问题:幻读。可重复读阻止的写事务包括update和delete(只给存在的表加上了锁),但是不包括insert(新行不存在,所以没有办法加锁),所以一个事务第一次读取可能读取到了10条记录,但是第二次可能读取到11条,这就是幻读。
    解决办法就是下面的“串行化”。

(四)串行化/序列化(Serializable)

  • 这是数据库最高的隔离级别,这种级别下,事务“串行化顺序执行”,也就是一个一个排队执行。
    这种级别下,“脏读”、“不可重复读”、“幻读”都可以被避免,但是执行效率奇差,性能开销也最大,所以基本没人会用。
  • 可避免幻读。读加共享锁,写加排他锁。这样读取事务可以并发,但是读写,写写事务之间都是互斥的,基本上就是一个个执行事务,所以叫序列化。

为什么会出现“脏读”?

  • 因为“select”操作没有规矩。

为什么会出现“不可重复读”?

  • 因为“update”操作没有规矩。

为什么会出现“幻读”?

  • 因为“insert”和“delete”操作没有规矩。

“读未提(Read Uncommitted)”能预防啥?

  • 啥都预防不了。

“读提交(Read Committed)”能预防啥?

  • 使用“快照读(Snapshot Read)”,避免“脏读”,但是可能出现“不可重复读”和“幻读”。

“可重复读(Repeated Red)”能预防啥?

  • 使用“快照读(Snapshot Read)”,锁住被读取记录,避免出现“脏读”、“不可重复读”,但是可能出现“幻读”。

“串行化(Serializable)”能预防啥?

  • 排排坐,吃果果,有效避免“脏读”、“不可重复读”、“幻读”,不过效果谁用谁知道。

参考网址1:https://www.2cto.com/database/201805/746874.html

参考网址2:https://baijiahao.baidu.com/s?id=1611918898724887602&wfr=spider&for=pc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值