48

一篇文章弄懂 MySQL 的事务隔离级别

 4 years ago
source link: https://www.tuicool.com/articles/JVzi6nN
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

先简单介绍一下MySQL中事务的概念,它是指: 用于实现某种行为的SQL语句的组合,可以是单条SQL语句,也可以是多条。 就像线程一样,MySQL服务器允许多个事务并发执行去更新某些数据,为了保障安全,MySQL提供了四种隔离级别,用来限制不同事务之间的干扰。

四种隔离级别如下(按照级别由低到高):

  • read uncommitted(读未提交)

  • read committed(读已提交)

  • repeatable read(可重复读)

  • Serializable(串行化)

接下来按照这个顺序分别进行演示。

**准备工作**

由于我本地服务器上只有一个root用户,为了后续的演示操作,所以需要再新建一个用户testB,并授予相应权限。方便起见,下文中root、testB开启的事务称为A、B。

一、read uncommitted(读未提交)

分别登录到用户root和testB,以表t_ss作为实验表,通过查询可以看到表t_ss是空的。

r2Y3M3i.png!web

分别将root和testB的隔离级别设置为 read uncommitted( 未提交)。

接着分别在root、testB中开启事务A、B,然后在B中向表t_ss插入一条数据。 这时候B中的事务还没有提交(commit),我们再在A中查表,可以看见, 即使B的事务还未提交,A中也可以查询到事务B插入的数据。

YFNFzeB.png!web

到这大家应该都能理解 read uncommitted(未提交) 的含义了,通俗来说就是: 即使事务B没有commit,其它事务也能读取到事务B更新的数据,即能够读取事务没有提交的数据。 这是事务隔离级别中等级最低的一个。

二、read committed(读已提交)

将root和testB的事务隔离级别设置为 read committed(读已提交)。

euyEfiE.png!web

同样开启两个事务,并在B中再插入一条数据,此时B事务未提交,当在A中查询时,发现并未查询到B新插入的数据。

QZR77bM.png!web

当commit事务B后,A成功读取到B插入的数据。

67zYVvj.png!web

总结一下,在read committed(读已提交)级别时, 其它事务只能读取事务B提交后的数据,未提交则读取不到。 这是大部分数据库的默认隔离级别。

三、repeatable read(可重复读)

将事务隔离级别设置为 repeatable read(可重复读) ,并分别开启事务。

r2mAJrV.png!web

A先查表,有两条数据,然后B插入一条数据并commit,A再查表,结果还是两条数据,但是B中查表所得结果是三条数据。(箭头指示命令执行顺序)

NZ3uiin.png!web

也就是说,当数据库处于repeatable read(可重复读)时, 同一个事务前后两次所读取的数据必须是一致的,无论事务B有没有插入数据。 它是MySQL的默认隔离级别。

四、Serializable(串行化)

将root的隔离级别设置为 Serializable(串行化) ,开启事务。当在事务A中查询表t_ss且未commit时,B事务一直在等待,到达指定时间后会报错,显示超时。

JJJRFb7.png!web

在事务A提交后,事务B才能够成功插入数据。

eYzimuM.png!web

Serializable(串行化)是等级最高,要求最严的事务隔离级别,在这种情况下, 其它事务必须等待当前事务commit后才能执行。

以上便是四种事务隔离级别,希望能给大家带来一点帮助。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK