InnoDB隔离级别

数据库隔离级别分为RU, RC, RR, Serialisable.以mysql 的InnoDB为例, 讲解一下数据库的隔离级别的原理是什么.

数据库实现隔离级别主要还是通过两个技术MVCC(多版本并发控制)和锁. 不同的隔离级别, MVCC的版本生成时机不同, 锁的范围和释放锁的时机也不同,就造成了不同的隔离级别.

首先我们来了解一下什么是MVCC和锁

基础知识

几种现象

我们先了解一下几个读现象: 脏读, 不可重复读, 幻读

脏读

脏读是指一个事务A能够读到另一个事务B还未提交的操作.这里的问题是如果事务B发生了Rollback显然会造成异常. 这是应该避免的一种错误现象.

不可重复读

不可重复读指的是, 事务中一条数据被重复读取的结果不一致. 假设如果有两个事务A, B并发执行. 事务A能够读取到事务B提交修改后的数据.这个现象针对的是update, delete操作

幻读

幻读指的是, 两个事务A, B并发执行, 事务A能够读取到事务B中新增的数据. 举个例子, 事务A执行select * from users where age > 0 and aget < 18;返回的结果是10条记录. 同时事务B执行insert into users(name, age) values('allen', 15);事务A再执行相同的select语句将会得到11条记录, 这就是幻读.

MVCC

多版本并发控制, 顾名思义就是在高并发的情况下, 数据库存在多个版本数据的情况.这个功能在mongoDB和HBase中都提供.如果没有提供MVCC的功能, 一个事务想要读取另一个事务正在修改的数据行的时候只能互斥等待, 这个时候并发能力就下降了, 而MVCC可以通过两种方式去构建出一个历史版本的数据.

  • 实时保留数据的一个或多个版本
  • 通过undo日志来构建版本

数据库的锁

首先我们要了解一个概念, 就是数据库的锁并不是加在数据行上面而是加在索引行上面的.
接着我们来了解一下, 什么情况下会加锁. 在一般修改数据记录的情况下就会触发加锁的操作比如insert, delete, update, 注意我们刚刚说过了加锁是加在索引行上面的, 如果这些操作没有走索引是不会加行级锁的而是加表级锁. 而select需要显示声明的情况下才会触发加锁操作:

  • select * from users where id = 1; // 不加锁
  • select * from users where id = 1 for update; // 加排它锁
  • select * from users where id = 1 lock in share mode; // 加共享锁

锁的分类

  • Share and Exclusive Locks: 共享锁相当于一种JAVA的读锁, 读不会上锁, 但是读写, 写写操作是互斥的.Exclusive loc则是一种排它锁, 都是互斥的.
  • Record Locks: 行级锁, 之前说过锁是加在索引行上的, 这个就是加在固定的索引行上加锁.比如: select * from users where id = 1 and id = 10 for update; 就是在id = 1和id=10的索引行上面加锁. 需要注意的是, 如果执行select * from users where name = 'allen' for update; 如果name列上没有加索引, 那么就会触发表锁, 会锁住全表
  • Gap Locks: 间隙锁, 它会锁住两个索引之间的区域, 比如select * from users where id > 1 and id < 10 for update; 那么会id在(1, 10)的索引区间加上锁.
  • Next-key Locks: 也是一种间隙锁, Gap Locks配合Record Locks形成一个闭区间的锁, 比如select * from users where id >= 1 and id <= 10;

四种隔离机制

隔离级别 脏读 不可重复读 幻读
Read Uncommit yes yes yes
Read Commited no yes yes
Read Repeatable no no yes
Serialisable no no no

Read Uncommit

这个模式下, 数据在发生修改以后就会释放锁, 而不是等到事务提交以后才释放锁. 这就导致各种问题, 会出现脏读, 更别提幻读了.

Read Commited

这个时候的锁是在事务提交以后释放的, 我们之前说过事务中的写操作是需要上锁的, 所以在释放锁之前读也读不到才对呀(事务中的读使用排它锁),一个事务能够读取到另一个事务提交以后的变更, 这是为什么呢?

谜底就是因为使用MVCC, MVCC的出现使得能够获取到最新版本的数据快照, 也就是说读出来的数据实际是通过MVCC机制构建出来的, 这里就不存在锁的问题.那么由于使用了MVCC, 也就是说重复执行select能够得到最新版本的数据快照, 也就是说能够读取到别的事务提交以后的最新变更, 这就导致了不可重复读的问题.

此外Read Commited还存在幻读的问题, 这是因为没有用间隙锁, 比如事务A中执行 select * from users where age > 10 and age < 18 for update; 一旦事务B中insert一条age=15的数据, 那么事务A可以读到这个新增的数据, 这就是幻读.

Read Repeatable

可重复读, 这个模式改进了一下所以可以在不可重复读和避免幻读都进行了规避.

  1. 通过MVCC机制从事务开始时select获取最新版本的数据, 事务进行中的所有select都是用这个版本的数据, 所以能够保证可重复读
  2. 锁范围调整, 在行锁的基础上添加了Gap Locks形成next-key locks, 在遍历过的索引行范围内都能够进行上锁, 从而阻塞其他事务往这个范围内insert数据, 避免幻读

Serialisable

串行化, 会自动将所有的select都转化成select lock in share mode执行, 也就是针对所有的读写操作都会加锁, 可靠性加强, 但是并发度大大降低.

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

推荐阅读更多精彩内容

  • 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式。同时数据库又是个高并...
    流浪冰007阅读 1,079评论 0 2
  • 转载自: https://tech.meituan.com/innodb-lock.html 前言:我们都知道事务...
    檀文渊阅读 477评论 0 0
  • 有一次,看博尔特的比赛,起跑慢了一个身位,最终仍夺冠。 听到一句赞,“你看人家。” 我想人们总是能从其他事物中,汲...
    周纪名阅读 242评论 0 0
  • 秋夕月明时,有丝竹之音,往来神女峰峰顶,山猿闻之皆鸣,达旦方渐止。这是怀王拜月后,巫山上第一次不眠不休的盛会。 神...
    薛紫夜阅读 3,113评论 35 86
  • 有关于孩子害怕什么,跟5岁儿子做了一个测验,颠覆了家长的预期,同上一辈人小时候害怕的东西还真的不一样呢!究竟是为什...
    尘世小书虫阅读 187评论 0 0