并发、锁、事务隔离级别

最近面试发现自己对Mysql的事务了解有点粗糙,正好看到沈剑大神的博客解答了我的疑惑,决定梳理一下,整理出自己的理解。
事务的隔离级别是一致性和并发性的折衷,而InnoDB通过锁和MVCC来实现,以避免脏读、不可重复读、幻读。

一.Mysql(InnoDB)的七种锁:
(1)共享/排它锁(Shared and eXclusive Locks,S锁和X锁)
共享锁(lock in share mode),共享锁之间是可以并行的,与排它锁之间是互斥的。排它锁(for update)与2种锁都是互斥的。
锁有2个操作,获取和释放,显式使用锁语句获取这两个锁,提交事务释放锁,也就是说在autocommit=1的情况下,获取锁后会马上释放。
并不是所有情况下,都需要显式定义锁,InnoDB的事务实际上是通过锁来实现一致性的,在某些事务级别下,Mysql会隐式的自动加锁。

(2)意向锁(Intention Locks)
意向锁是表级锁,意向锁就是在声明锁前先加一个意向,它也分共享(IS)、互斥(IX)两种。意向锁之间都是不互斥的,但是与互斥共享锁之间,只有IS和S是兼容的,其他都是互斥的。
InnoDB中表锁和行锁共存,这就是依赖意向锁来实现的,试想,如果对一个表加行锁,之后又有一个连接对该表加表锁,这时首先要去检查该表是否有表锁,然后再检查表中的每一行是否有行锁,这就发生了遍历。如果通过意向锁来实现呢?首先查看是否有表锁,再查看表上是否有意向锁,如果有意向锁,再看意向锁是否和自己申请的锁互斥,Bingo,问题解决。

(3)记录锁(Record Locks)
对索引记录进行加锁,未走到索引则会变为表锁。

(4)间隙锁(Gap Locks)
锁住索引记录的间隔,若事务隔离级别为读提交(Read Commit,RC),间隙锁会自动失效。

(5)临键锁(Next-key Locks)
记录锁与间隙锁的组合,它封锁范围,也封锁记录。若事务隔离级别为读提交(Read Commit,RC),临间锁会自动失效。

记录锁,间隙锁,临键锁都是针对索引进行锁定,若没有走到索引则会变为表锁。所以,这里我们看到InnoDB的索引不仅影响了其性能,还对锁的互斥产生影响。

(6)插入意向锁(Insert Intention Locks)
插入意向锁是间隙锁的一种(专门实施在索引上,只针对插入操作),InnoDB使用强互斥锁实现一致性,使用插入意向锁提高插入并发。

(7)自增锁(Auto-inc Locks)
有三种模式,配置innodb_autoinc_lock_mode决定其级别(不同级别性能不同)。主要解决id的自增问题,表级锁,对性能会有一定影响。

二.MVCC
Mysql能实现较高的并非主要是因为其MVCC机制,其核心原理是:
(1)写任务发生时,将数据克隆一份,以版本号区分;
(2)写任务操作克隆的数据,直至提交;
(3)并发读任务可以读取旧版本的数据,以不至于阻塞。
Mysql MVCC旧版本的数据存储在undo日志(回滚段)中,以减少对原有体系的冲击。
Mysql InnoDB中未加锁的读是快照读,即通过MVCC机制实现,该机制提高了InnoDB的性能。
(MVCC通过为数据提供多个版本,使数据的读写互不冲突,支持RC、RR隔离级别,在RC级别下,快照读每次读取到最新的提交数据,而RR级别下,快照读每次读取到的是第一次读操作之前提交的数据)。

三.事务与锁
事务的隔离级别是通过锁来实现的(RC、RR级别下有MVCC支持):
(1)读未提交:select不加锁,可能出现脏读;
(2)读已提交:普通select快照读,加锁的select、update和delete会使用记录锁(重复键检查和外键约束检查条件下会锁区间);
(3)可重复读:普通select快照读,加锁的select、update和delete会使用记录锁、或者间隙锁、临键锁,防止读到幻影记录;
(4)串行化:select隐式转换为in share mode,会被update和delete互斥。

附录:
MVCC在一定程度上解决了幻读的问题,然而并没有完全解决。
MySQL InnoDB的可重复读并不保证避免幻读,需要应用使用加锁读来保证。而这个加锁度使用到的机制就是next-key locks。
两种RR级别下的幻读:
(1)两个连接中的事务:一个事务增加一个记录,另一个事务先查询,后根据该唯一键增加,会阻塞或报错;
(2)两个连接中的事务:一个事务增加一个记录,另一个事务先查询,后更新该记录,再查询,能查到最新记录;
可以通过读的时候加锁,解决该问题。

(InnoDB用的最多的隔离级别是RC,默认隔离级别是RC)。

(这篇文章内容主要出自沈剑的博客,归纳下来,让自己印象更深刻些)
参考文献:
https://mp.weixin.qq.com/s/wGOxro3uShp2q5w97azx5A(沈剑博文聚合)
https://blog.csdn.net/wufaliang003/article/details/81905661(Mysql七种锁)
https://blog.csdn.net/gao_yu_long/article/details/73739559(MVCC)
https://www.jianshu.com/p/e937830bc2de(意向锁)
https://www.cnblogs.com/JiangLe/p/6362770.html(自增锁,innodb_autoinc_lock_mode)
http://blog.sina.com.cn/s/blog_499740cb0100ugs7.html(RR级别下的幻读问题)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容