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查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都 ...
随机推荐
- Apache URLRewrite 原理及配置实现
看一下网站上的一些 URL.您是否发现一些类似于 http://yoursite.com/info/dispEmployeeInfo. ... 99&type=summary的 URL?或者, ...
- [转]android中listview点击事件失效
首先说明一下我想实现的功能: 点击某个item之后,让其颜色发生变化.如果变化网上有很多例子,我就不班门弄斧了.Listview之所以点击没有反应是因为上图中绿色部分(自己定义的一个继承BaseAda ...
- Codeforces Beta Round #6 (Div. 2 Only) A. Triangle 水题
A. Triangle 题目连接: http://codeforces.com/contest/6/problem/A Description Johnny has a younger sister ...
- poj 2828 buy Tickets 用线段树模拟带插入的队列
Buy Tickets Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2 ...
- 原来通过修改dns加快app store下载速度的确有效
说来惭愧,这几天休假,并没有做什么技术上的修行.小伙伴推荐我一款avg游戏<11eyes 罪与罚与被诅咒的少女>,说是神作.但是app store上卖rmb118元,起初并没有什么兴趣去购 ...
- HDU 4579 Random Walk (解方程组)
Random Walk Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)Total ...
- VirtualBox 4.3.18 启动虚拟机时显示不能加载 R3模块并退出故障解决一例
VirtualBox 升级到 4.3.1x后一直问题不断.搜了些资料,发现这货从最近的某个版本开始,为了安全,要校验进程完整性,那些在运行时要注入Virtualbox进程的模块都要进行校验.于是乎出现 ...
- 15KW电动机380V及220V时的电流分别为多少
15KW电动机380V及220V时的电流分别为多少 当用电电压为380V时:P=UICOSφ/1.72,此时电流为: I=15KW/380V/0.83(COSφ,功率因数)/1.72x1000=27. ...
- java 调用shell命令
原文:http://kongcodecenter.iteye.com/blog/1231177 Java通过SSH2协议执行远程Shell脚本(ganymed-ssh2-build210.jar) ...
- Eclipse maven构建springmvc项目
原文地址: http://www.cnblogs.com/fangjins/archive/2012/05/06/2485459.html 一.背景介绍 对于初学者,用maven构建项目并不是一件容易 ...