Mysql笔记:事务隔离级别理解
2021/12/25 19:08:21
本文主要是介绍Mysql笔记:事务隔离级别理解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
这个问题其实有很多人都已经教科书式的总结了很多遍,如:
隔离级别中文描述此级别问题(面试官喜欢用这个)READ UNCOMMITED未提交读脏读READ COMMITED提交读不可重复读REPEATABLE READ可重复读幻读SERIALIZABLE串行化锁
但是在这个表格中最后一列的问题因何产生,很多人会不明白其中的缘由。我先说下我的理解,然后再来一点点解释:
事务隔离的四个级别可以先用“事务是否可并发”来划分成两个对立面来理解:
事务不可并发在 Mysql 中只有 SERIALIZABLE 这一级别满足;其它的当然是事务可并发了;事务不可并发,Mysql 选择了串行化这一实现方式,因此引入了锁,也带来了性能问题;事务可并发,因此在多个并发的事务期间,我们并不知道哪个事务的哪段逻辑(begin/rollback/commit)会在下一个时间片内被执行;
并发事务带来的问题
在上面的描述中,2、3是对1的一个扩展,2不难理解,但是 3 可能有些生硬,我们可以简单的换种理解方式,
假设同一时间有两个事务: A & B ,并且事务 A 执行 update,事务 B 执行 select。假设事务的开启、提交、回滚及事务中执行的 Action 都能在一个 cpu 时间片内完成,那么可把 A&B 的事务拆成如下逻辑调用段:
#事务A事务B
1beginbegin2updateselect3commitcommit4rollbackrollback
基于上面的假设,我们再来理解事务并发情况下各种问题的产生:
脏读
A begin=> update 后让 cpu同时B begin=> select,但是事务 B 很心大,并没有去验证 A 的有效性,读到了 A update 后的数据;A 在下一个 cpu 时间又得到了调度,A 发现自己刚才的操作无效了,A rollback 得到了执行,但是它无法告知 B 了,所以 B 读到的数据是无效的;不可重复读知道了脏读的原因后,为了解决这个问题,Mysql 规定 B 读的数据只能读取已经 commit 状态的数据:A begin=> update 后让 cpu同时 B begin=> select,这次 B 很小心地验证 A 的数据是否 commit 了,B 这次读到了 A begin 以前的数据;事务 A 在下一个 cpu 时间又得到了调度,A commit 了;B 再次 select,但是已经 select 到了 A commit 后的数据了,B 在 A commit 前后读到了两次不一样的数据,即不可重复读了;幻读知道了不可重复读的原因后,Mysql 又规定,既然 B 第一次读到的是 A commit 前的数据,那么在事务 B 中后面无论多少次 select 都只能读到 A commit 之前的数据。但是问题又来了:这次 A 不是 update 了,而是 insert,B select 也不是单条了,而是 select range;B 在 A commit 前后两次 select range 会发现结果的数量不一至;这就是幻读;InnoDB 针对幻读也做了处理:MVCC,在每一行后都有隐藏的两列版本号来实现;大致与处理不可重复读相同;
这篇关于Mysql笔记:事务隔离级别理解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-25如何部署MySQL集群资料:新手入门教程
- 2024-12-24MySQL集群部署资料:新手入门教程
- 2024-12-24MySQL集群资料详解:新手入门教程
- 2024-12-24MySQL集群部署入门教程
- 2024-12-24部署MySQL集群学习:新手入门教程
- 2024-12-24部署MySQL集群入门:一步一步搭建指南
- 2024-12-07MySQL读写分离入门:轻松掌握数据库读写分离技术
- 2024-12-07MySQL读写分离入门教程
- 2024-12-07MySQL分库分表入门详解
- 2024-12-07MySQL分库分表入门指南