【mysql】隔离级别以及其验证实例

目录

前言

读未提交(Read Uncommitted)

读已提交(Read Committed)

可重复读(Repeatable Read)

串行化(Serializable)


前言

在事物与隔离级别中我们讲解了事务与不同隔离级别,以及可能产生的问题,本节我们通过简单的例子来验证不同隔离级下可能存在的问题。

首先我们需要一张测试表以及初始数据:

create table test_cases
(
    id         int         not null,
    group_name varchar(40) not null
    unique (id)
);

INSERT INTO health_tree.test_cases (id, group_name) VALUES (1, 'test1');

笔者用的mysql5.7,默认隔离级别是REPEATABLE-READ,可通过“select @@tx_isolation;”查询

可以通过以下命令设置隔离级别

#read uncommitted 
#read committed
#repeatable read
#serializable
set session transaction isolation level read uncommitted ;
读未提交(Read Uncommitted)

1、启动事务a

【mysql】隔离级别以及其验证实例_第1张图片

2、启动事务b,并更新数据但不提交

【mysql】隔离级别以及其验证实例_第2张图片

3、事务a再次取数据,可以看到读取到了,事务b未提交的数据

【mysql】隔离级别以及其验证实例_第3张图片

4、若回滚(rollback)事务b

【mysql】隔离级别以及其验证实例_第4张图片

5、事务a读取值变回

【mysql】隔离级别以及其验证实例_第5张图片

这就是未提交读下的脏读现象

读已提交(Read Committed)

1、启动事务a

【mysql】隔离级别以及其验证实例_第6张图片

2、启动事务b,并更新数据但不提交

【mysql】隔离级别以及其验证实例_第7张图片

3、事务a读取数据,数据未变化

【mysql】隔离级别以及其验证实例_第8张图片

4、事务b提交事务

【mysql】隔离级别以及其验证实例_第9张图片

5、事务a读取数据,读取到事务b提交更新的更新数据

【mysql】隔离级别以及其验证实例_第10张图片

虽然读已提交解决了脏读现象,但可能出现不可重复读的问题。

可重复读(Repeatable Read)

1、启动事务a

【mysql】隔离级别以及其验证实例_第11张图片

2、事务b更新数据并提

【mysql】隔离级别以及其验证实例_第12张图片

3、读取事务a,数据未变解决不可重复读问题

【mysql】隔离级别以及其验证实例_第13张图片

4、再次开启事务b,插入一条新数据并提交

【mysql】隔离级别以及其验证实例_第14张图片

5、在事务a中进行相同数据插入

【mysql】隔离级别以及其验证实例_第15张图片

虽然查询并未查询到id为2这条数据,但是在进行插入的时候还是“感知”到这条数据已经存在,这个感知我们可以当作我们一直觉得的“幻读”。这里重点提一下,经常看到对幻读这样的理解:幻读是事务a 执行两次 select 操作得到不同的数据集,即 select 1 得到 1 条记录,select 2 得到 2 条记录,这难到不是不可重复读的表现吗?

正确的理解应该是:事务中 select 操作得到的结果数据状态无法支撑后续的数据操作。比如上面的插入id为 2 的数据是报“ Duplicate entry”。

串行化(Serializable)

相信看到这里大家对mysql事物操作也有了一个基本的掌握,以及对前面的几种隔离级别也有了更深的了解,在这里笔者想把串行化这一点的例子交给读者自己去完成,相信大家看了前面的内容,这部分的操作也可以做到信手拈来,通过实践自己解决“可重复读”隔离级别下产生的幻读问题吧!

相信能耐心读到这里的读者,对mysql技术都有一定的追求,在这里笔者推荐大家阅读:高性能MySQL

电子书版本,扫码回复:mysql

【mysql】隔离级别以及其验证实例_第16张图片

你可能感兴趣的:(mysql实践与常见问题,mysql,数据库)