今天在阅读《高性能MySQL》的第一章时,遇到了四大隔离等级的概念,反复琢磨了许久,最后弄出了几张图来帮助记忆,希望对路过的博友们有帮助。


目录

  • 概念定义
  • 三大问题之一 —— 脏读图解
  • 三大问题之二 —— 不可重复读图解
  • 三大问题之三 —— 幻读图解
  • 隔离等级 —— 提交读图解
  • 隔离等级 —— 可重复读图解
  • 隔离等级 ——— 可串行化图解


概念定义



三大事务问题:

  • 脏读:事务可以读取另一个事务未提交的数据。
  • 不可重复读:在同一个事务中,执行相同的查询,查询出不一样的结果。
  • 常对应update语句
  • 脏读:事务A在读取某个范围的记录时,另一个事务B在这个范围插入了新的记录,当事务A再次读取该范围的记录时,出现了新的记录。(也叫幻行)
  • 常对应insert和delete语句


事务的四大隔离等级分别为:

  • READ UNCOMMITTED(未提交读)
  • 事务的修改,没有提交,在其他事务可见
  • 会出现脏读、不可重复读、幻读
  • READ COMMITTED(提交读)
  • 一个事务的数据从开始到提交之前,对于其他事务不可见。
  • 会出现不可重复度,幻读
  • REPEATABLE READ(可重复读)
  • 同一个事务中,多次读取同样的记录,结果是一致的。
  • 会出现幻读
  • SERIALIZABLE(可串行化)
  • 强制事务串行处理,上表级锁
  • 三个问题都不会出现
  • 效率很低,一般不用

三大问题之一 —— 脏读图解

Mysql 事务刷盘 mysql事务脏读_数据

在这里,事务1和事务2同时对员工信息表进行操作。

在脏读比较重要的点是

事务2并没有提交修改的情况下,事务1就已经读到了这个值

三大问题之二 —— 不可重复读图解

Mysql 事务刷盘 mysql事务脏读_数据_02

在这里,事务1和事务2同时对员工信息表进行操作。

在不可重复读的比较重要的点是

事务2在事务1还在执行的情况下完成提交,导致事务1前后读取的数据不一致 导致之前的数据丢失,所以叫不可重复读

三大问题之三 —— 幻读图解

Mysql 事务刷盘 mysql事务脏读_串行化_03

在这里,事务1和事务2同时对员工信息表进行操作。

在幻读中比较重要的点是

在幻读中比较的是查询数据的项数,而不是项里面的数据 项数变多,导致看起来像产生了幻觉。

隔离等级 —— 提交读图解

Mysql 事务刷盘 mysql事务脏读_数据_04

因为未提交读三个问题都会出现,没什么需要讲解的。

因此这里直接讲解提交读。

在这里需要注意的

事务A在读取完数据之后,并没有提交事务, 事务A和事务B仍然在继续执行 也就是说事务A给小红那一行数据上锁只在读取的一瞬间

读取完之后立刻释放,锁的释放与否与事务是否提交并没有太大的关系。

隔离等级 —— 可重复读图解

Mysql 事务刷盘 mysql事务脏读_数据_05

个人认为可重复读是最难理解的一种隔离等级了。

从图中需要解释的是

事务A在进行其他操作的同时,事务B在对小红的信息进行修改。 照常理来思考,事务A最后应该读取出2000,后面的数据操作才是顺理成章的。

但是在这个隔离等级中,

事务A小红的工资,若非事务A自己修改,否则查询结果恒定不变

这个隔离等级在不同的DBMS有不同的实现,MySQL的InnoDB引擎中采用了一种“MVCC”方法,利用“快照读”,来实现可重复读这个隔离等级。

这个方法涉及另一块原理,这里不铺开描述。

隔离等级 ——— 可串行化图解

Mysql 事务刷盘 mysql事务脏读_Mysql 事务刷盘_06


可串行化是最一劳永逸的办法了

操作非常简单,就是一旦一个事务进行操作的时候,就把整个表锁起来,其他事务完全没有办法操作。

但是这样做必定会导致效率低下,因此现实中基本不会采取这个做法。