一、导言

关于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中的锁、隔离等级和读场景的更多相关文章

  1. MySQL实战 | 06/07 简单说说MySQL中的锁

    原文链接:MySQL实战 | 06/07 简单说说MySQL中的锁 本文思维导图:https://mubu.com/doc/AOa-5t-IsG 锁是计算机协调多个进程或纯线程并发访问某一资源的机制. ...

  2. 在MySQL中设置事务隔离级别有2种方法:

    在MySQL中设置事务隔离级别有2种方法: 1 在my.cnf中设置,在mysqld选项中如下设置 [mysqld] transaction-isolation = READ-COMMITTED 2 ...

  3. 谈谈MySQL中的锁

    谈谈MySQL中的锁 锁的定义 ​ 在生活中锁的例子就非常多了,所以应该很容易理解锁的含义.在计算机领域,可以这样来概述,锁是计算机协调多个进行进程并发访问某一资源的机制. ​ 在数据库中,锁也是一个 ...

  4. MySQL系列(五)---总结MySQL中的锁

    MySQL中的锁 目录 MySQL系列(一):基础知识大总结 MySQL系列(二):MySQL事务 MySQL系列(三):索引 MySQL系列(四):引擎 概述 MyISAM支持表锁,InnoDB支持 ...

  5. 你了解MySQL中的锁吗?

    MySQL中的锁,分为全局锁.表级锁.行锁 全局锁 全局锁的意思就是,对整个数据库实例加锁,它的命令是FTWRL Flash tables with read lock 这个命令的语义是,使整个库处于 ...

  6. MySQL中InnoDB锁不住表的原因

    MySQL中InnoDB锁不住表是因为如下两个参数的设置: mysql> show variables like '%timeout%'; +-------------------------- ...

  7. mysql中的锁表语句查看方法汇总

    mysql> show status like 'Table%'; +----------------------------+----------+ | Variable_name | Val ...

  8. MySQL中的锁(表锁、行锁)

    锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...

  9. mysql中不同事务隔离级别下数据的显示效果--转载

    事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都 ...

随机推荐

  1. phpRedis函数使用总结

    /*1.Connection*/ $redis = new Redis(); $redis->connect('127.0.0.1',6379,1);//短链接,本地host,端口为6379,超 ...

  2. USACO 2017 FEB Gold visitfj 最短路

    题意 有一幅n*n的方格图,n <= 100,每个点上有一个值.从(1,1)出发,走到(n,n),只能走四联通.每走一步花费t,每走三步需要花费走完三步后到达格子的值.求最小花费的值. 拆点,d ...

  3. [转] Eclipse的Tomcat插件安装

      Eclipse的Tomcat服务器插件tomcatPlugin是由Sysdeo公司开发的,其下载地址是:http://www.eclipsetotale.com/tomcatPlugin.html ...

  4. UESTC 2015dp专题 A 男神的礼物 区间dp

    男神的礼物 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/65 Descri ...

  5. C# MATLAB混合编程

    我附带把matlab配置过程也给大家上传上来.[转载]终于学会C#调用matlab函数了,原来这么简单(也可以下载附件查看)自己的配置: (1)Microsoft Visual Studio 2005 ...

  6. SSM+Maven(教程二):Idea快速入门SSM+Maven框架。

    快速入门须知 这篇文章,直接应用已经搭建好的SSM框架.一般在公司里面,考虑框架的搭建.封装等问题,都由研发经理或者架构师完成,所以对于刚入门的小白来说,在去搭建整合花费的时间会很多很多.对于理解能力 ...

  7. CentOS 6.9/7通过yum安装指定版本的PostgreSQL扩展PostGIS

    一.安装PostGIS扩展插件(24_10) // 安装EPEL源 # rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-rele ...

  8. CMSIS-SVD 系统视图说明

    CMSIS 到底是什么? 先来看看ARM公司对CMSIS的定义: ARM® Cortex™ 微控制器软件接口标准 (CMSIS) 是 Cortex-M 处理器系列的与供应商无关的硬件抽象层. CMSI ...

  9. .Net 加密 哈希

    一.DES加解密 DES一共就有4个参数参与运作:明文.密文.密钥.向量.其中这4者的关系可以理解为: 密文=明文+密钥+向量: 明文=密文-密钥-向量: 为什么要向量这个参数呢?因为如果有一篇文章, ...

  10. .NET:动态代理的 “5 + 1” 模式

    背景 什么叫“动态代理”,代理模式我们都知道,动态代理就是动态生成的代理(采用Emit). 重量级的ORM和IOC产品离不开动态代理,作为开发人员,多数情况不用关注动态代理的内部实现机制,但是了解其一 ...