事务原理及MVCC

事务概述

在MySQL中的事务是由存储引擎实现的,而且支持事务的存储引擎不多,我们主要讲解InnoDB存储引擎中的事务。所以,今天我们就一起来分析和探讨InnoDB的事务机制,希望能建立起对事务底层实现原理的具体了解

image-20200326101714003

数据库事务具有ACID四大特性。ACID是以下4个词的缩写:

  • 原子性(atomicity) :事务最小工作单元,要么全成功,要么全失败
  • 一致性(consistency):事务开始和结束后,数据库的完整性不会被破坏
  • 隔离性(isolation) :不同事务之间互不影响,四种隔离级别为RU(读未提交)、RC(读已提交)、RR(可重复读)、SERIALIZABLE (串行化)
  • 持久性(durability) :事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失

隔离级别

事前准备

我们需要创建一个表

1
2
3
4
CREATE TABLE t (
  id INT PRIMARY KEY,
  c VARCHAR(100)
) Engine=InnoDB CHARSET=utf8;

然后向这个表里插入一条数据

1
INSERT INTO t VALUES(1, '刘备');

现在表里的数据就是这样的

1
2
3
4
5
6
7
mysql> SELECT * FROM t;
+----+--------+
| id | c     |
+----+--------+
|  1 | 刘备  |
+----+--------+
1 row in set (0.01 sec)

未提交读(READ UNCOMMITTED/RU)

脏读:一个事务读取到另一个事务未提交的数据

如果一个事务读到了另一个未提交事务修改过的数据,那么这种隔离级别就称之为未提交读(英文名:READ UNCOMMITTED ),示意图如下:

image-20200326102355671

如上图,Session A 和Session B 各开启了一个事务,Session B 中的事务先将id 为1 的记录的列c 更新为’关羽’ ,然后Session A 中的事务再去查询这条id 为1 的记录,那么在未提交读的隔离级别下,查询结果就是’关羽’ ,也就是说某个事务读到了另一个未提交事务修改过的记录。但是如果Session B 中的事务稍后进行了回滚,那么Session A 中的事务相当于读到了一个不存在的数据,这种现象就称之为脏读,就像这个样子

image-20200326102522861

脏读违背了现实世界的业务含义,所以这种READ UNCOMMITTED 算是十分不安全的一种隔离级别

已提交读(READ COMMITTED/RC)

不可重复读:一个事务因读取到另一个事务已提交的update。导致对同一条记录读取两次以上的结果不一致

这里有两个重点

如果一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值,那么这种隔离级别就称之为已提交读(英文名:READCOMMITTED ),如图所示:

image-20200326102709917

文章目录
  1. 1. 事务原理及MVCC
    1. 1.1. 事务概述
    2. 1.2. 隔离级别
      1. 1.2.1. 事前准备
      2. 1.2.2. 未提交读(READ UNCOMMITTED/RU)
      3. 1.2.3. 已提交读(READ COMMITTED/RC)
|