三张图片告诉你:啥是脏读、不可重复读、幻读

文章目录

  • 前言
  • 一、数据库事务的ACID是什么?
  • 二、脏读、不可重复读、幻读的问题
    • 1.脏读
    • 2.不可重复读
    • 3.幻读
  • 三、MVCC机制


前言


一、数据库事务的ACID是什么?

提到数据库事务,我们都知道有的四大特性 ACID,那么都分别是什么意思呢?

  • 原子性(Atomicity)
    原子性是指事务包含的所有操作要么全部成功,完全应用到数据库,要么全部失败回滚,不会对数据库产生任何影响。
  • 一致性(Consistency)
    一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
    换句话说,数据库中的数据开始是正确的,随着状态转移,总是保持正确的状态。
  • 隔离性(Isolation)
    隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
    即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
    关于事务的隔离性数据库标准定义了多种隔离级别,也就是我们今天要讲的主题内容。
  • 持久性(Durability)
    持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

二、脏读、不可重复读、幻读的问题

SQL标准定义了4类隔离级别:

  • READ UNCOMMITTED (读未提交)
  • READ COMMITTED (不可重复读、读已提交)
  • REPEATABLE READ (可重复度)
  • SERIALIZABLE (串行化)

这四种隔离级别的效率依次递减,读未提交效率最高,串行化效率最低。
同样伴随着效率的问题,效率越高,问题越多。

隔离级别 脏读 不可重复读 幻读
READ UNCOMMITTED (读未提交) 有可能 有可能 有可能
READ COMMITTED (不可重复读、读已提交) 不可能 有可能 有可能
REPEATABLE READ (可重复度) 不可能 不可能 有可能
SERIALIZABLE (串行化) 不可能 不可能 不可能

1.脏读

一个事务中查询出来的数据,有可能是其他事务还未提交的数据。
也就是我在开启一个事务后,select出来的数据,有可能不是数据库最终的数据。

三张图片告诉你:啥是脏读、不可重复读、幻读_第1张图片

2.不可重复读

在同一个事务中,同一条SQL语句,在不同时刻,查询出来的内容不一致。
这种现象就叫 不可重复读。

三张图片告诉你:啥是脏读、不可重复读、幻读_第2张图片

3.幻读

很多人分不清楚幻读和不可重复读。
幻读指的是,在同一事务下,某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。

不可重复读指的是:同一个SQL执行多次查询,得到的结果不一致。

幻读: 根据同一个条件,查询出来的结果 和 按照相同条件进行update或者insert操作时候出现逻辑不一致的情况。
举个例子:
在同一个事务中,先根据 条件 age = 20 可以查询出2条数据,然后我再根据 age=20 进行update,结果更新了 3条数据,与预期结果不一致。 这种现象就叫做幻读,好像之前读取的数据是假的。
再举一个插入的例子:
在同一个事务中,id是主键。根据id=100查询不到数据,然后我进行insert语句,插入一条id=100的数据,结果插入失败,提示id=100的记录已存在。这也出现了insert与select预期不一致,好像之前select查询的数据有错误,这种现象也叫做幻读。
三张图片告诉你:啥是脏读、不可重复读、幻读_第3张图片

三、MVCC机制

提到MySQL的事务隔离机制,很多人都会提到一个词,就是MVCC机制。
MVCC (Multiversion Concurrency Control),翻译为:多版本并发控制技术。
Mysql就是通过这种机制解决的可重复读的问题。

MVCC机制解决了,MySQL实现可重复度的情况下,还提高了并发的性能。如果没有MVCC机制,要实现可重复读可能就得通过加锁的方式,那么如果对整张表进行加锁,对数据的并发就会有很大的影响,如果每次都对行加锁呢,也同样会在性能上有影响。
为了解决这些问题,才有出现了MVCC机制。
MVCC是指的一种机制,各家的数据库厂商都有自己的实现,并非是一种标准,Oracle,PostgreSQL等其他数据库系统也都实现了MVCC,但是各自的实现机制并不相同。

MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。大多数的MVCC都实现了非阻塞的读操作,写操作也只锁定必要的行。

下一篇文章我们一起解密MySQL产生幻读的根本原因

你可能感兴趣的:(MySQL,mysql,数据库,幻读,innodb)