mysql的事务隔离级别

mysql的事务隔离级别

​ 经常看到mysql事务的隔离级别,每次都是简单看一下就略过去了,根本就没有理解,这次深入理解了一下,特地记录一下,方便下次进行回顾。

事务隔离级别

  • 读未提交:就是事务A能读取到事务B未提交的数据,导致出现脏读。
  • 读提交:就是事务A能读取到事务B已经提交的数据,事务C未提交,那么事务A就读取不到,解决了脏读问题,但是未解决可重复读的问题。
  • 可重复读:就是事务A从开启到结束,读取到的数据都是一样的,不受事务B的影响。
  • 串行化:顺序执行
隔离级别脏读不可重复读幻读
读未提交
读提交
可重复读
串行化

上面的解释比较抽象,难以理解,下面通过实例进行解析,然后在回来看,就会显得清晰了。

实例

首先看一下如何设置mysql的隔离级别

## 查看当前的事务级别
show variables like 'transaction_isolation'

## set [作用域] transaction isolation level [事务隔离级别]
## SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
## 其中作用于可以是 SESSION 或者 GLOBAL,GLOBAL 是全局的,而 SESSION 只针对当前回话窗口。隔离级别是 {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} 这四种,不区分大小写。
## 设置为读提交,其它隔离级别类似,设置完需要关闭当前连接,从新开一个才会生效
set global transaction isolation level read committed; 

读未提交

设置为读未提交:

set global transaction isolation level read uncommitted;

最开始用户ID为1的age=18

顺序事务A事务B
1BEGIN;BEGIN;
2update user set age = 20 where user_id = 1;
3select * from user where user_id = 1;
4ROLLBACK;
5COMMIT;
  1. 事务A和事务B同时开启事务
  2. 事务B更新了用户ID为1的age等于20,未提交事务
  3. 事务A查询用户ID为1的,得到用户age等于20,读取到了事务B未提交的数据
  4. 这时事务B由于各种原因,回滚了事务,这时用户的age等于18
  5. 事务A拿着age等于20,做了各种事情,然后提交了事务,就会导致结果不对

以上就是:脏读

读提交

set global transaction isolation level read committed;

最开始用户ID为1的age=18

顺序事务A事务B
1BEGIN;BEGIN;
2update user set age = 20 where user_id = 1;
3select * from user where user_id = 1;
4COMMIT;
5select * from user where user_id = 1;
6COMMIT;
  1. 事务A和事务B同时开启事务
  2. 事务B更新了用户ID为1的age等于20,未提交事务
  3. 事务A查询用户ID为1的,得到用户age等于18,未读取到事务B未提交的数据,说明不存在脏读的问题了
  4. 这时事务B提交了事务
  5. 事务A再次查询,得到的age等于20,和上面3查询到的不一致,就出现了不可重复读的问题
  6. 事务A提交事务

可重复读

set global transaction isolation level repeatable read;

最开始用户ID为1的user_name=张三

顺序事务A事务B
1BEGIN;BEGIN;
2select * from user where age = 20;
3update user set user_name = ‘李四’ where age = 20;
4COMMIT;
5select * from user where age = 20;
6INSERT INTO user(user_name,age) VALUES(‘李四’,‘20’);
7select * from user where age = 20;
8COMMIT;
  1. 事务A和事务B同时开启事务
  2. 事务A查询age为20的,得到为张三
  3. 事务B更新了age为20的用户名称变成李四
  4. 事务B提交事务
  5. 事务A查询age为20的,得到用户名称还是张三,说明事务A在开始事务到未提交事务之前,查询到的都是一样的,不受其它事务的影响,在本次实例中也就是事务B,解决了不可重复读的问题
  6. 这时事务B插入了一条数据
  7. 事务A再次查询age为20的,还是只有一条用户名称等于张三的,说明可重复的解决了换读的问题
  8. 事务A提交了

串行化

串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束。

可重复读隔离级别的实现方案

可参考如下文章理解:

  • https://zhuanlan.zhihu.com/p/117476959/
  • https://tech.meituan.com/2014/08/20/innodb-lock.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值