MySQL中的锁、隔离等级和读场景
一、导言
关于MySQL中的锁还有隔离等级这类话题,其概念性的解释早已泛滥。记住其概念,算不上什么。更重要的是思考:他们的区别和联系在哪儿,为什么会有这样的概念。
1)MySQL的锁(Lock)分为行锁(Row Lock)和表锁(Table Lock),锁本身又分为读锁(Read Lock)和写锁(Write Lock)。
2)隔离等级分为Read uncommitted, Read committed, Repeatable reads, Serializable
3)在常见的读场景(Read phenomenon)中,会出现Dirty read, Non-repeatable reads以及Phantom Reads
为什么要这么分类,三个类别的概念是如何相互联系的。这里谈谈我的思考。
二、发现问题:Read phenomenon
所谓Dirty read,脏读,如下例所示
select age from students where id = 9
update table students set age = 12 where id = 9
select age from students where id = 9
rollback
脏读的关键在于,左侧的事务A中的第二次读操作读到了事务B并没有提交的数据,导致出错。关键点在于事务B还没有提交。
-------------------------------------------------------------------------------------------------------------------------------
所谓Non-repeatable reads,不可重复读,如下例所示
select age from students where id = 9
update table students set age = 12 where id = 9
commit
select age from students where id= 9
commit
不可重复读的关键,在于左侧的事务A中的第二次读操作读到了事务B中已经提交的数据,导致出错。关键点在于事务B已经提交。
-----------------------------------------------------------------------------------------------------------------------------------
Phantom Read,幻读,如下例所示
select * from students where id > 3 and id < 99
insert into students (id, name, age) values (12, "zs", 27)
commit
select * from students where id > 3 and id < 99
commit
幻读的关键,在于在集合统计层面上,出现了不可重复读,是一种特殊的不可重复读。不可重复读是修改数据,而幻读是新增数据。
-----------------------------------------------------------------------------------------------------------------------------------
那为什么要分为这三种层次的read phenomena?
这是因为,这三个层次实现了B事务的“缩小化”和“叠加”。从最开始B事务和A事务是交集状态,到后来B事务位于A事务内部, 再到最后由单个记录变为多条记录。本质上是这样一种递进关系。
二、分析问题:Isolation
为了依次避免上述每一个问题,就需要逐步采取更为严格的措施。这也就出现了隔离状态(Isolation)
1)啥都不避免,最烂的约束,就是Read uncommitted。这个uncommitted单词是有意味的,说白了就是未提交,也就是脏读中出现的情况。
2)避免脏读,就是Read committed。这个committed单词也是有意思的,是已提交。如此也就排除了脏读的情况,但是仍会有不可重复读和幻读的情况。
3)避免脏读和不可重复读,就是 Repeatable reads。对应的正好是non-repeatable。但是仍会有幻读情况。
4)避免所有情况,那就是Serializable。
三、解决解决:Lock
这样逐级进行分类,实际上也为解决这些问题提供了一种策略,那就是“锁”。
读锁(Read Lock)还有一个学名,叫做Shared Lock(共享锁)。写锁(Read Lock)也叫作排它锁(Exclusive Lock)
某线程一旦获得写锁,其他的线程都将无法获得任何锁,无论写锁还是读锁,都会被挂起,直到该写锁释放。
某线程获得了读锁,其他线程仍旧可以获得读锁,但无法获取写锁。直到读锁释放。
我们来锁看看是怎么解决上述read phenomena的
1)Read uncommitted。这个就是啥锁都不要。对吧。裸奔
2)Read committed。这个是要做到事务B能够完整提交,那好,就用一个写锁,保证事务B在执行过程中始终拥有一个写锁。至于事务A中的读,就不给锁了,或者换一个说法,每次select的时候会获得一个读锁,select操作完成后立即释放。总之读锁是不可能维持整个事务过程的。如此一来,避免了脏读,却无法避免不可重复读。
3)Repeatable reads。这下除了写锁,还得必须保证读锁了,也就是说,事务A必须拥有读锁,事务B必须有写锁,锁的生存期为整个事务过程。两者不可交叉。不可重复读的问题也解决了。
4)Serializable。如何克服统计层面上的幻读呢?现在我们不仅要保证单条数据记录的可重复读,还要保证多条记录在统计意义上的可重复读,那就是有采用表锁了(Table Lock),当然也不一定要锁全表,所以最为准确的说法,是用范围锁(Range Lock),把多条记录都上锁。讲到这里,也就很清楚了,1-3是不需范围锁的。
四、结语
锁,隔离等级,读场景,就是这么关联到了一起:发现问题,分析问题,解决问题。
MySQL中的锁、隔离等级和读场景的更多相关文章
- MySQL实战 | 06/07 简单说说MySQL中的锁
原文链接:MySQL实战 | 06/07 简单说说MySQL中的锁 本文思维导图:https://mubu.com/doc/AOa-5t-IsG 锁是计算机协调多个进程或纯线程并发访问某一资源的机制. ...
- 在MySQL中设置事务隔离级别有2种方法:
在MySQL中设置事务隔离级别有2种方法: 1 在my.cnf中设置,在mysqld选项中如下设置 [mysqld] transaction-isolation = READ-COMMITTED 2 ...
- 谈谈MySQL中的锁
谈谈MySQL中的锁 锁的定义 在生活中锁的例子就非常多了,所以应该很容易理解锁的含义.在计算机领域,可以这样来概述,锁是计算机协调多个进行进程并发访问某一资源的机制. 在数据库中,锁也是一个 ...
- MySQL系列(五)---总结MySQL中的锁
MySQL中的锁 目录 MySQL系列(一):基础知识大总结 MySQL系列(二):MySQL事务 MySQL系列(三):索引 MySQL系列(四):引擎 概述 MyISAM支持表锁,InnoDB支持 ...
- 你了解MySQL中的锁吗?
MySQL中的锁,分为全局锁.表级锁.行锁 全局锁 全局锁的意思就是,对整个数据库实例加锁,它的命令是FTWRL Flash tables with read lock 这个命令的语义是,使整个库处于 ...
- MySQL中InnoDB锁不住表的原因
MySQL中InnoDB锁不住表是因为如下两个参数的设置: mysql> show variables like '%timeout%'; +-------------------------- ...
- mysql中的锁表语句查看方法汇总
mysql> show status like 'Table%'; +----------------------------+----------+ | Variable_name | Val ...
- MySQL中的锁(表锁、行锁)
锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...
- mysql中不同事务隔离级别下数据的显示效果--转载
事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都 ...
随机推荐
- Java并发(十六):并发工具类——Exchanger
Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法交换数 ...
- python开发_filecmp
filecmp模块用于比较文件及文件夹的内容,它是一个轻量级的工具,使用非常简单.python标准库还提供了difflib模块用于比较文件的内容.关于difflib模块,且听下回分解. filecmp ...
- Codeforces Round #305 (Div. 1) A. Mike and Frog 暴力
A. Mike and Frog Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/547/pr ...
- HDU 4705 Y (2013多校10,1010题,简单树形DP)
Y Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submiss ...
- Two-transistor circuit replaces IC
Linear Technology's recently introduced LTC4300 chip buffers I2C clock and data lines to and from a ...
- Wix使用整理(一)
由于工作需要,学习了一段时间Wix,总算小有起色.鉴于国内Wix 的普及和使用有限,这里将个人遇到得问题和解决方案记录下来,以便交流和相互促进. Wix :全称 Windows Installer ...
- asp.net core更进内容
ASP.NET Core 是对 ASP.NET 的一次意义重大的重构.本文介绍了 ASP.NET Core 中的一些新概念,并且解释了它们如何帮助你开发现代的 Web 应用程序. 章节: 什么是 AS ...
- Appium+python自动化9-SDK Manager
前言 SDK Manager到有哪些东西是必须安装的呢? 一.SDK Manager 1.双击打开SDK Manager界面
- 替换Android系统镜像system.img的方法
之前改动了Android的系统源代码的framework层代码,定制ROM.通过make之后会生成三个镜像文件userdata.img.system.img.ramdisk.img三个文件.这个时候我 ...
- STL源码剖析——hashtable
二叉搜索树具有对数时间的搜索复杂度,但是这样的复杂度是再输入数据有足够的随机性的假设上哈希表在插入删除搜索操作上也具有常数时间的表现,而且这种表现是以统计为基础,不需要依赖输入元素的随机性 hasht ...