mysql事务隔离级别(基于InnoDB)

1. 序言

本文记录了InnoDB的四种隔离级别,并在不同的隔离级别之下实际运行mysql,看看不同的隔离级别会带来的问题。

2. 一些名词

autocommit: mysql5.7默认开启,每一个session就是一个只包含自己的事务,只要sql没有报错就会自动提交,报错时是否提交取决于error本身。

commit: commit意味着session提交,变更就可以被其他session看见,并释放锁;

rollback:rollback取消session的所有变更,并释放锁;

3.隔离级别和解决的问题

一般事务之间有三个导致数据错乱的问题:

1.脏读,2.不可重复读,3.幻读

 

隔离级别有四个,分别是:

read uncommited:读未提交

read commited: 读已提交 - 解决脏读

repeatable read:可重复度 - 解决不可重复读

serialiable:序列化 - 解决幻读

 

4.分析

1.读未提交 - 导致脏读

解析:读未提交的事务隔离级别是最低的隔离级别,不同的事务可以读取到别的事务最新的操作(不一定提交)。

此事务隔离级别和脏读比较容易理解,就是事务 A 读取到 事务 B 未提交(commit)的操作(如更新),之后事务B进行回退了(rollback),那么A读到的数据就是错误的。

2.读已提交 - 解决脏读,导致不可重复读

解析:读已提交意味着不同的事务之间只能读取别的事务已经提交的事务,解决了脏读,但未解决不可重复读

例子:

注意第6行B新增了一条数据,如果事务级别是读未提交,第七行A应该可以查出来刚刚新增的数据,但没有。

直到第9行B提交了数据,第10行A才查到了B提交的数据,所以解决了脏读的问题。

但是,注意到,第10行和第7行,是属于A的同一个事务,同样的sql条件查询的结果竟然不一样,这就是不可重复读的问题。

3.可重复读 - 解决不可重复读

解析:可重复读的意思是同一个事务内,同样的sql语句得到的结果是一致的(但可能会出现幻读),不可重复读可以参考上面读已提交的例子。具体的是基于mvcc,也就是多版本并发控制实现的,具体另外说。

例子:

与读已提交不同的是,在第10行B提交了新增的事务之后,第11行A仍然没有查到B提交的事务,解决了不可重复读的问题。

但有一个比较神奇的事情是,如果在事务A里面对事务B提交的事务涉及到的数据进行update操作,那么事务A就可以看得到事务B新的提交。这是因为update操作是基于当前读而不是快照读的(mvcc概念,另行查看)。所以也算是一个幻读的问题。

4.串行化 - 万事皆空

没啥好解释的,各个事务串行执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值