MySQL事务隔离级别

一、并发场景下事务的数据问题

1.1 脏读

事务A 读取了 事务B 为提交的数据,事务B 回滚,那么 事务A 读的就是脏数据

1.2 不可重复读

事务A 读取 同一数据,事务B 在这个过程中进行修改,导致 事务A 每次读的数据都不一致。

1.3 幻读

有一个学校,所有学生都打了疫苗,事务A 需要将所有学生都标注为已打疫苗状态。 事务B 这时候插入了一条未打疫苗的新生,事务A 发现数据没改完,和发生幻觉一样,这就是幻读。

二、MySQL的四种隔离级别

2.1 隔离级别介绍

隔离级别效果
读未提交(read-uncommitted)一个事务没提交时,它操作的结果能被另一条事务锁能看到。
不可重复读(read-committed)一个事务没提交时,它操作的结果不能被另一条事务所能看到。
可重复读(repeatable-read)一个事务查询一条数据,即使这条数据被别的事务所更改,但是这个事务查询的开始和结束的这个时间段内都是一致的。
串行化(serializable)正如物理书上写的,串行是单线路,顾名思义在MySQL中同一时刻只允许单个事务执行,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。(其它事务是可以开启事务的,并不是说其它事务不能在开启事务了,只是在同时开启完事务后不能同时更改。读加读锁,写加写锁。)

2.2 隔离级别的问题解决情况

脏读不可重复读幻读
读未提交(RU)×××
读提交(RC)××
可重复读(RR)
串行(xíng)化(S)

三、隔离级别的修改和查看

3.1 查看当前会话的隔离级别

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)

3.2 查看当前系统会话的隔离级别

mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

3.3 设置会话的隔离级别,隔离级别由低到高设置依次为

set session transaction isolation level read uncommitted;
set session transaction isolation level read committed;
set session transaction isolation level repeatable read;
set session transaction isolation level serializable;

3.4 设置当前系统的隔离级别,隔离级别由低到高设置依次为

set global transaction isolation level read uncommitted;
set global transaction isolation level read committed;
set global transaction isolation level repeatable read;
set global transaction isolation level serializable;

四、案例分析

4.1 读未提交(RU)

左窗口,修改陈梦的年龄为26,并未提交事务:

在这里插入图片描述

右窗口,查询陈梦的年龄,查出了左窗口修改后并未提交的数据:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dv3dnyxU-1630395910905)(https://imgcdn.wangchuangcode.cn./note/20210805/1628156857618.png ''图片title'')]

造成了脏读的问题。

4.2 读提交(RC)

左窗口,修改马龙30,并未提交事务:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4jLSe4n8-1630395910907)(https://imgcdn.wangchuangcode.cn./note/20210805/1628157246421.png ''图片title'')]

右窗口,查询马龙的年龄,发现依然为32:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-22dH7Q40-1630395910912)(https://imgcdn.wangchuangcode.cn./note/20210805/1628157269679.png ''图片title'')]

左窗口提交事务,右窗口再次查看,发现马龙的年龄成为了30:

在这里插入图片描述

此隔离级别,可解决脏读问题,但造成了不可重复读问题。

4.3 可重复读(RR)

首先,左窗口开启事务,进行查询所有数据,右窗口同样开始起事务并查询所有数据,左窗口更新马龙的年龄为29并未提交:

在这里插入图片描述

右窗口进行查询,发现马龙的年龄依然为30:

在这里插入图片描述

左窗口提交,右窗口继续查询,发现马龙的年龄依然为30:

在这里插入图片描述

右窗口提交事务后,再次查询,发现马龙的年龄变为了29:

在这里插入图片描述

这样就实现了在这一事务内可以重复读取一条数据。

4.4 串行化(SERIALIZABLE)

窗口1:开启事务,并且查询id为1的数据:

在这里插入图片描述

窗口2:开启事务,查询id为1的数据后并进行修改,但是事务1中查询已经加锁了(我怀疑是行锁的共享锁,因为事务2也能查这条数据,说明事务2也能持有这个共享锁,事务1也不能进行修改,造成死锁。但是这两个事务又能修改id不为1的数据,由此可见,串行化中的查询此id,加的是行的共享锁)

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值