轻松学会mysql隔离级别

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读这几类问题

因为mysql有自动提交事务的功能,所以先把自动提交关了,

  • 关闭自动提交:set autocommit=0 或者 set autocommit = off;
  • 关闭自动提交后需要手动开启事务:START TRANSACTION
  • 手动提交:COMMIT

一、首先来看下Read uncommitted读未提交:

  • 再把事务隔离级别设成Read uncommitted:SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

上面过程直接上图解释:

开启两个会话:

然后这是数据库:

准备工作完成,进入正题:

会话1开启事务1,

会话2开启事务2,

事务1查询第一条数据, 

事务2修改第一条数据的money,

事务1再次查询第一条数据,

问题来了,由于事务2并没有执行commit,也就是没有提交,事务1却查到了事务2没提交的数据,这就是脏读

脏读:脏读发生在一个事务A读取了被另一个事务B修改,但是还未提交的数据。

Read uncommitted(读未提交)  不能解决脏读、不可重复读(下文 Read committed(读已提交)的时候演示)、幻读(下文演示)的问题。

 

二、Read committed读已提交:

  • 再把事务隔离级别设成Read committed :SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED

解决脏读:

步骤还是同上面的步骤一样,详细过程就不写了,直接上图:

事务1: 

事务2:

事务1:

 

到这里可以看出事务1还是1000,并没有出现脏读,OK,解决了。读已提交顾名思义就是事务2  commit后,事务1才会读到修改后的结果,继续。

事务2:

事务1:

那么还有不可重复读,不可重复读是什么?不可重复读 :在一个事务中,两次查询的结果不一致(针对的update操作)

继续演示不可重复读:

事务1:

事务2:

事务1:

问题来了,事务1第一次查询是1000,第二次查询是900,二次查询不一样,出现了不可重复读。

Read committed(读已提交)  :能解决脏读,不能解决不可重复读、幻读(下文演示)的问题。

三、Repeatable read 可重复读(mysql默认的隔离级别,oracle默认隔离级别是读已提交):

  • 再把事务隔离级别设成Repeatable read :SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

步骤:

事务1:

事务2:

事务1:

到了这里,还是1000,OK,解决了不可重复读。但是moeny不是到900了吗?我现在对事务1继续做update操作还是用1000还是用事务2更新后的900呢?继续:

事务1:

可以看到,虽然我之前查的money=1000,但是实际上我用的是900进行200相加的,最后变成1100,完全符合逻辑。解决。

因为InooDB在可重复读隔离级别规避了幻读问题,了解详细原因可以去百度,这里我直接改用读已提交测试,步骤如下:

事务1:

 

事务2:

事务1:

 问题来了,本来一开始查出来是2行记录,后面再查1次,莫名其妙的多了一行记录,出现幻觉了,这就是幻读。

幻读:在一个事务中,两次查询的结果不一致(针对的insert、delete操作) 

Repeatable read(可重复读)  :能解决脏读、不可重复读,不能解决幻读(下文演示)的问题。

四、Serializable  串行化:

  • 再把事务隔离级别设成Serializable  :SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE

步骤:

事务1:

事务2:

由于事务1没有commit,因为串行化的时候默认给select * from test加锁的,共享锁(S锁)没有解锁的情况下是不能加排它锁(X锁)的,所以这句话会一直处于阻塞状态,如图:

直到我们事务1 commit了,事务2才能执行。 

事务1:

事务2:

那条阻塞的语句在commit后马上就执行了,现在查一下

事务1:

 

这样幻读就解决了,除非事务2 commit,不然事务1是不会看见3条记录的。

Serializable(串行化)  :能解决脏读、不可重复读、幻读的问题。

隔离级别演示完毕。

留下几个问题思考:

  • 为什么可重复读级别时,事务1在事务2更新前后读到的数据会是一样?
  • 为什么可重复读可以规避幻读?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值