近期,不少开发的朋友们总问我,面试时总被问到MySQL事务隔离级别基础问题,答不上来咋办,今天特意将之前写的一篇文章发出来,希望大家能有所收获!

一、什么是事务

  1. 概念:事务是包含了一组有序的数据库操作命令的序列,它是数据库并发操作的最小控制单位。
  2. 特性
  • 原子性:事务包含的数据库操作命令要么都执行,要么都不执行。
  • 一致性:当事务完成时,数据库处于稳定而一致的状态。即事务执行后,数据库数据要符合规定,而且所有数据查询的结果是一致的。
  • 隔离性:多个事务同时执行时,他们之间是互不干扰的。
  • 永久性:一旦事务提交成功,它引发的变化也就永久保存了下来,硬件与应用程序发生错误也不能改变。

二、在并发执行事务时会发生什么问题呢?

  1. 脏读:一个事务读到另一个事务未提交的更新数据。
  2. 不可重复读:一个事务读到另一个事务已提交的更新数据。
  3. 幻读:一个事务读到另一个事务已提交的新插入的数据。

三、四种隔离级别

1. Read Uncommitted(读未提交数据):一个事务在执行过程中可以看到其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。

2. Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新。

3. Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他其他事务对已有记录的更新。

4. Serializable(串行化):事务执行的时候不允许别的事务并发执行。

四、通过例子理解事务的4种隔离级别

首先,我们使用test数据库,新建test表,如下:



MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_mysql 默认事务隔离级别


接着开启两个客户端。

第1级别:Read Uncommitted(读取未提交内容)

所有事务都可以看到其他未提交事务的执行结果,该级别会引发脏读。

例子:


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_MySQL_02


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_MySQL_03


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_事务未提交 别人能读取到吗_04


脏读意味着在这个事务中(A中),事务B虽然没有提交,但它任何一条数据变化,事务A都可以看到!

第2级别:Read Committed(读取提交内容)

这个级别是大多数数据库系统的默认隔离级别,但MySQL不是;在这个级别,一个事务只能看见已经提交事务所做的改变;这种隔离级别出现的问题是——不可重复读(Nonrepeatable Read)。

例子:


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_数据_05


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_mysql 默认事务隔离级别_06


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_事务未提交 别人能读取到吗_07


第3级别:Repeatable Read(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行;此级别可能出现的问题——幻读(Phantom Read):当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行;InnoDB和Falcon存储引擎通过多版本并发控制(MVCC)机制解决了该问题。

例子:


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_隔离级别_08


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_MySQL_09


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_MySQL_10


第4级别:Serializable(可串行化)

这是最高的隔离级别,它在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争,不推荐在实际应用场景中使用。

例子:


MySQL与spring默认值事务隔离级别 mysql事务的默认隔离级别_数据_11


后记:今天数据库事务隔离级别的介绍就到这里