MySql教程

MySQL脏读、幻读和不可重复读

本文主要是介绍MySQL脏读、幻读和不可重复读,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

脏读

当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据)

A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚,那么A事务读取到的数据就是脏数据

这种情况经常发生于转账与取款操作中

脏读

幻读

在事务A中按照某个条件先后两次统计数据库记录数,两次统计结果的记录数不同

事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据操作并执行了提交;这个时候事务A读取的数据总量和之前统计的不一样,平白无故的多了几条数据

幻读

不可重复读

在事务A中先后两次读取同一个数据,两次读取的结果不一样

  • 事务A在执行读取操作,由于整个事务A较大,前后读取同一条数据需要经历很长的时间;
  • 事务A第一次读取数据,事务B执行修改操作,然后事务A第二次读取到的数据与第一次不同,即数据不重复了

读取前后事务A还未结束,即在同一个事务中,事务A前后几次读取的数据不一致

不可重复读

区别

不可重复读 vs. 幻读

  1. 不可重复读是读取了其他事务更改的数据,针对update操作(某一条数据记录变了

    解决:使用行级锁

  2. 幻读是读取了其他事务新增的数据,针对insertdelete操作(数据记录数变了

    解决:使用表级锁

不可重复读 vs. 脏读

  1. 脏读读到的是其他事务未提交的数据
  2. 不可重复读读到的是其他事务已提交的数据

数据库事务

  1. 原子性(Atomicity):一个事务是一个不可分割的工作单位,包含的操作要么全部成功,要么全部失败
  2. 一致性(Consistency):事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态
  3. 隔离性(Isolation):事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰
  4. 持久性(Durability):事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响

隔离级别

  1. 由低到高依次为Read uncommittedRead committedRepeatable readSerializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题
  2. 一般来说,隔离级别越低,系统开销越低,可支持的并发越高,但隔离性也越差

隔离级别

  1. Read uncommitted并发可能导致很多问题,且性能提高有限,使用很少;
    Serializable强制事务串行,并发效率很低,只有对数据一致性要求极高且可接受没有并发时使用
  2. 大多数数据库中,默认的隔离级别是Read committed(Oracle)或Repeatable read(简称RR
  3. InnoDB默认隔离级别是RR
    (在SQL标准中,RR是无法避免幻读的,但InnoDB实现的RR避免了幻读)

参考资料:

  • 快速理解脏读、不可重复读、幻读和MVCC - 云+社区 - 腾讯云 (tencent.com)
  • 深入学习MySQL事务:ACID特性的实现原理 - 编程迷思 - 博客园 (cnblogs.com)
这篇关于MySQL脏读、幻读和不可重复读的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!