详解MySQL 数据库隔离级别与MVCC
知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个数据库开发实战,手把手教大家学习《详解MySQL 数据库隔离级别与MVCC》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!
Mysql是我们日常生产与学习中最常接触到的数据库之一,今天讲一讲在Mysql(或者说其他类似的数据库)中存在的隔离级别以及用来提高效率的多版本并发控制(MVCC)。
一、隔离级别
首先我们需要提到一个概念:事务。什么是事务?事务就是完成一个基础操作的一系列操作语句的一个集合。例如我要将200元从账户A转移到账户B,那么我可能会进行一下的操作:
a.验证账户A中的余额是否大于200元。
b.将账户A中的余额减200元。
c.将账户B中的余额加200元。
我们就将上面的abc三个操作成为一个事务。
这时,我们会注意到我们所说的一个事务有可能是由多条语句组合而成的,而事务又存在原子性,即事务的执行过程中是不能被打断的,这就带来一个问题,如果在这三步执行过程中有另外的语句插入进来执行,是否会对结果产生影响,因为此时破坏了事务的原子性。而这种插入的情况在并发的环境下是十分常见的。因此,我们(或者说是数据库引擎)就需要在一个事务的执行过程中对它进行“保护”,即保证外界的其他事务的语句不能随意的插进正在执行的事务语句之中,来保证事务的正常执行。这时候我们很容易的会想到“加锁”这个方法。这其实是一种很笼统的说法,因为加锁虽然能够保证事务的正常执行,但是却会带来较大的额外开销,因此合适的时候选择合适的加锁方式对查找效率的影响就非常大。而“锁”得严不严,就区分除了集中不同的隔离级别。
READ UNCOMMITED(读未提交)
这种隔离界别下,读取数据的时候不受任何影响。即你甚至可以读取一个正在被其他事务修改的数据,想读就读,想改就改。这当然开销很小,但是会带来许多的问题,比如“脏读”。即读取到了正在修改但是却还没有提交的数据,这就会造成数据读取的错误。从性能上来说,READ UNCOMMITED不会比其他级别好太多,但是却带来了非常多的麻烦的问题,因此在实际中很少使用这个个立即被。
READ COMMITED(提交读/不可重复读)
这个级别在READ UNCOMMITED的基础上添加了一些规定,是一些数据库的默认隔离级别。它与READ UNCOMMITED的区别在于,它规定读取的时候读到的数据只能是提交后的数据。举个例子,数据a在上一次提交之后的值是1,这时候有一个线程进来对a进行修改,将a修改为2,但是此时并未提交事务(COMMIT),在这种情况下,READ UNCOMMITED级别下读取到的a的值就是当前的2,但是READ COMMITED级别下读取到的还是上一次提交之后的值,即a为1,必须到修改线程将a的值变为2这个事务提交之后读取到的a的值才是2。这个级别所带来的问题就是不可重复读。即上一个时间读取到的a的值是1,但是随着修改线程对事务的提交,a的值变为了2,这时候读到的值就是2了,即执行两次相同的读取操作得到的值却不一样。
不可重复读同脏读的区别在于,脏读是一个事务读取了另一未完成的事务执行过程中的数据,而不可重复读是一个事务执行过程中,另一事务提交并修改了当前事务正在读取的数据。
REPEATED READ(可重复读)
REPEATED READ在READ COMMITED的基础上又添加了一些约束性的规则,它也是MySQL数据库的默认隔离级别。简单来说就是在一个事务的执行期间禁止其他事务对相应的数据进行修改,这就彻底使得一个事务的执行过程中所查询到的数据一定是一致的,即解决了脏读和不可重复读的问题,但是却带来了新的问题,即“幻读”。
“幻读”指的是在一个事务执行过程中虽然禁止了对相应数据的修改,但是其他的事务依然可以插入数据,这时候第一个事务就会发现会“莫名其妙”多出来一些数据,像是出现了幻觉似的。幻读和不可重复读都是读取了另一条已经提交的事务(这点同脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
SERIALIZABLE (可串行化)
这是最严格的一个隔离级别。它通过强制事务串行执行,避免了幻读的问题。但是这种隔离级别的开销极大,一般也不常使用。
各种隔离级别与可能的问题关系如下:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁 |
|---|---|---|---|---|
| READ UNCOMMITED | YES | YES | YES | NO |
| READ COMMITED | NO | YES | YES | NO |
| REPEATED READ | NO | NO | YES | NO |
| SERIALIZABLE | NO | NO | NO | YES |
二、MVCC
试想一下,如果每次SQL操作为了保证数据的一致性与准确性,都需要加一个行级锁的话,非常可靠,但是带来的系统开销与查找效率的下降也是非常明显的,因此MVCC就是为了解决这种矛盾而产生的。
首先MVCC会在表中的每一行记录后面保存两个隐藏的列,一个保存行的创建时间,一个保存行的过期(删除)时间。这个时间值并不是真的时间,而是一个系统版本号。事务开始的时刻的系统版本号作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
- INSERT:为新插入的每一行保存当前的系统版本号作为行版本号。
- DELETE:为删除的每一行保存当前的系统版本号最为行删除版本号。
- UPDATE:更新其实应该理解为插入一条新的数据,并删除原来数据的过程,即为新插入的数据保存当前的系统版本号作为行版本号,并为删除的数据保存当前的系统版本号作为删除版本号。
- SELECT:只查询满足下列条件的行:
a.行版本号小于等于事务版本号
b.删除版本号未定义或者大于事务版本号
保存了这两个版本号之后绝大多数的操作都可以在不加锁的情况下进行正确的操作,保证了性能和效率。
值得注意的是MVCC只在READ COMMITED和REPEATABLE READ两个隔离级别下工作。
终于介绍完啦!小伙伴们,这篇关于《详解MySQL 数据库隔离级别与MVCC》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布数据库相关知识,快来关注吧!
MySQL EXPLAIN语句的使用示例
- 上一篇
- MySQL EXPLAIN语句的使用示例
- 下一篇
- MySQL如何快速批量插入1000w条数据
-
- 美好的煎蛋
- 这篇文章真是及时雨啊,好细啊,感谢大佬分享,已收藏,关注师傅了!希望师傅能多写数据库相关的文章。
- 2023-05-05 19:59:11
-
- 合适的鱼
- 赞 ??,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢作者大大分享技术贴!
- 2023-02-15 12:58:18
-
- 数据库 · MySQL | 43分钟前 | MySQL · JSON查询 · JSON_TABLE · mysql JSON数组 JSON_TABLE
- MySQL JSON 数组怎么展开成多行查询
- 490浏览 收藏
-
- 数据库 · MySQL | 12小时前 | MySQL · SQL查询 · ROW_NUMBER · mysql group by 分组查询 ROW_NUMBER
- MySQL 分组后怎么取每组最新一条记录
- 423浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL 第几万页开始变慢:用稳定排序和游标条件替代深 OFFSET
- 405浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL JSON 数组检索要不要建多值索引:从 MEMBER OF 到不能排序的边界
- 463浏览 收藏
-
- 数据库 · MySQL | 1天前 | MySQL · 连接管理 · 服务器配置 · max_connections MySQL 9.4 back_log 连接突发
- MySQL 9.4 为什么把 back_log 默认值提到 10000:连接突发时先看这条边界
- 488浏览 收藏
-
- 数据库 · MySQL | 2天前 | MySQL · InnoDB · server_memory · 内存配置 ·
- MySQL 9.4 的 server_memory 怎么用:限制默认内存估算,不是给 InnoDB 加缓存
- 215浏览 收藏
-
- 数据库 · MySQL | 5天前 |
- MySQL 8.4 隐藏索引怎么试:不删索引也能验证查询计划
- 133浏览 收藏
-
- 数据库 · MySQL | 6天前 |
- MySQL 分区表怎么处理跨分区唯一键:分区列约束与建表取舍
- 501浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 152次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 84次使用
-
- ClickPrompt
- ClickPrompt是一款专为AI提示词编写者设计的开源在线工具,支持Stable Diffusion绘图、ChatGPT对话及GitHub Copilot代码辅助。提供Prompt自动生成、一键运行、社区分享及可视化优化功能,帮助用户高效获取精准AI输出。
- 42次使用
-
- PromptHero
- PromptHero是专业的AI提示词搜索引擎与优化平台,支持Stable Diffusion、Midjourney等主流模型。提供海量提示词库、分类搜索、在线课程及社区互动,助力用户高效生成高质量AI图像与文本。
- 25次使用
-
- Stable Diffusion Prompt Book
- 深入解析OpenArt推出的Stable Diffusion Prompt Book,这本免费的开源提示词指南涵盖从基础语法到高级技巧,提供风格化词库与参数建议,助您优化AI绘画生成效果。
- 28次使用
-
- MySQL中 LBCC 和 MVCC 的理解及常见问题示例
- 2022-12-29 372浏览
-
- 一文详解MySQL不同隔离级别都使用什么锁
- 2022-12-30 423浏览
-
- MySQL脏读幻读不可重复读及事务的隔离级别和MVCC、LBCC实现
- 2022-12-30 117浏览
-
- MySQL的多版本并发控制MVCC的实现
- 2022-12-28 462浏览
-
- mysql隔离级别详解及示例
- 2023-01-01 358浏览

