MySQL事务的隔离级别验证

前言:

        事务是保障数据正确的重要方式,事务具有原子性、一致性、隔离性和持久性四个属性。本篇文章主要说一下基于MySQL事务中的隔离性。MySQL事务的隔离性分四个级别,分别是RU(读未提交)、RC(不可重复读)、RR(可重复读)、Serializable(串行化)。不同的隔离级别,可以避免脏读、不可重复、幻读的发生,具体如下图: 

        本篇文章将通过Navicat图形化工具来验证MySQL的隔离级别,具体操作请阅读正文:

正文:

0.提前准备:

        i. 数据准备:

# 创建数据库
CREATE DATABASE test;
# 选择数据库
USE test;
# 创建用户表
CREATE TABLE user (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
) ;
# 插入数据
INSERT INTO `user` (id,name)  VALUES (1,'小周');
INSERT INTO `user` (id,name)  VALUES (2,'小张');
INSERT INTO `user` (id,name)  VALUES (3,'小王');

        ii. 临时修改MySQL隔离级别语句:

set session TRANSACTION ISOLATION level READ UNCOMMITTED ;	

        iii.  临时手动提交事务语句:

set autocommit = 0;

1. MySQL隔离级别使用RU(读未提交)时,出现脏读验证:

        我们在Navicat中启动三个查询窗口,在不同窗口执行不同的语句,来验证我们的猜想。

时间事务窗口一事务窗口一无事务窗口
T1set autocommit = 0;set autocommit = 0;           
T2set session TRANSACTION ISOLATION level READ UNCOMMITTED ;set session TRANSACTION ISOLATION level READ UNCOMMITTED ;默认隔离级别
T3BEGIN ;BEGIN ;
T4update user set name ='小周2' where id = 1 ;
T5select * from user ;select * from user ;select * from user ;
T6ROLLBACK;
T7select * from user ;select * from user ;
T8COMMIT ;COMMIT ;

        T5时间内三个窗口同时查询情况如下图。窗口一事务更新的数据没有提交时,就被窗口二事务获取到。如果窗口一事务在之后的时间中发送回滚,窗口二事务则获取了脏数据,即出现了脏读。

 

         窗口一事务在T6时,发生了回滚,T7时间内三个窗口的查询结果如下,三个窗口数据一致了。

 

2. MySQL隔离级别使用RC(不可重复读)时,解决了脏读,验证存在不可重复读:

        我们在Navicat中启动三个查询窗口,在不同窗口执行不同的语句,来验证我们的猜想。

时间事务窗口一事务窗口一无事务窗口
T1set autocommit = 0;set autocommit = 0;           
T2set session TRANSACTION ISOLATION level READ COMMITTED ;set session TRANSACTION ISOLATION level READ COMMITTED ;默认隔离级别
T3BEGIN ;BEGIN ;
T4update user set name ='小周2' where id = 1 ;
T5select * from user ;select * from user ;select * from user ;
T6COMMIT ;
T7select * from user ;select * from t_user ;
T8COMMIT ;

         T5时间内三个窗口同时查询情况如下图。窗口一事务更新的数据没有提交时,窗口二事务没有获取到窗口一事务未提交的数据,避免了脏读。

         窗口一事务在T6时,提交了事务,T7时间内窗口二事务再次读取数据,数据发生了改变,造成了不可重复读。

4.MySQL隔离级别使用RR(不可重复读)时,解决了脏读,解决了不可重复读:

        我们在Navicat中启动三个查询窗口,在不同窗口执行不同的语句,来验证我们的猜想。

时间事务窗口一事务窗口一无事务窗口
T1set autocommit = 0;set autocommit = 0;           
T2set session TRANSACTION ISOLATION level REPEATABLE READ ;set session TRANSACTION ISOLATION level REPEATABLE READ ;默认隔离级别
T3BEGIN ;BEGIN ;
T4update user set name ='小周2' where id = 1 ;
T5select * from user ;select * from user ;select * from user ;
T6COMMIT ;
T7select * from user ;select * from t_user ;
T8COMMIT ;

       T1-T6,步骤不再复述,直接展示T7时间,T7时间内窗口二事务再次读取数据,数据没有改变,避免了不可重复读。

5. MySQL隔离级别使用RR(不可重复读)时,存在幻读:

        我们在Navicat中启动三个查询窗口,在不同窗口执行不同的语句,来验证我们的猜想。

时间事务窗口一事务窗口一无事务窗口
T1set autocommit = 0;set autocommit = 0;           
T2set session TRANSACTION ISOLATION level REPEATABLE READ ;set session TRANSACTION ISOLATION level REPEATABLE READ ;默认隔离级别
T3BEGIN ;BEGIN ;
T4insert into user VALUES (4,'小韩') ;
T5select * from user ;select * from user ;select * from user ;
T6COMMIT ;
T7select * from user ;select * from t_user ;
T8insert into user VALUES (4,'小韩') ;
T9COMMIT ;

        窗口二事务在T7时间时,查询数据结果如下:

         窗口二事务在T7时间时,没有第四条数据,所有决定在T8时间插入第四条数据,结果不能插入,这出现了幻读。

        提示:所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。

        不可重复读和幻读的区别是:不可重复读是指读到了已经提交的事务的更改数据(修改或删除),幻读是指读到了其他已经提交事务的新增数据

       防止读到更改数据,需要对操作的数据添加行级锁,防止操作中的数据发生变化;防止读到新增数据,需要添加表级锁,将整张表锁定,防止新增数据。

6. MySQL隔离级别使用Serializable(串行化)时,解决幻读:

        我们在Navicat中启动三个查询窗口,在不同窗口执行不同的语句,来验证我们的猜想。

时间事务窗口一事务窗口一无事务窗口
T1set autocommit = 0;set autocommit = 0;           
T2set session TRANSACTION ISOLATION level SERIALIZABLE;set session TRANSACTION ISOLATION level SERIALIZABLE;默认隔离级别
T3BEGIN ;BEGIN ;
T4insert into user VALUES (4,'小韩') ;
T5select * from user ;select * from user ;select * from user ;
T6COMMIT ;
T7select * from user ;select * from t_user ;
T8insert into user VALUES (4,'小韩') ;
T9COMMIT ;

     窗口二事务在T5时间内,会一直在处理中。如果窗口一事务不提交,窗口二事务就会等锁超时,即事务必须串行化执行。

         窗口二事务在T7时间时,窗口一事务以及提交,可以执行查询,并且发现有第四条数据,就不会在插入数据,避免了幻读。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hanxiaozhang2018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值