并发事务解决方案MySQL数据库锁机制

脏读、不可重复读和幻读都是数据库读一致性问题,需要由数据库提供一定的事务隔离机制来解决。

(1)锁机制

解决写-写冲突问题。在读取数据前,对其加锁,防止其它事务对该数据进行修改。

悲观锁

往往依靠数据库提供的锁机制。

乐观锁

大多是基于数据版本记录机制来实现。

(2)MVCC多版本并发控制

解决读-写冲突问题。不用加锁,通过一定机制生成一个数据请求时间点时的一致性数据快照, 并用这个快照来提供一定级别 (语句级或事务级) 的一致性读取。这样在读操作的时候不需要阻塞写操作,写操作时不需要阻塞读操作。

MySQL/InnoDB锁机制

加锁方式

两段锁

加锁/解锁是两个不相交的阶段,加锁阶段:只加锁,不解锁。解锁阶段:只解锁,不加锁。

锁类型

锁粒度

按照锁粒度维度来看,MySQL数据库根据不同的存储引擎可以有表级锁、页级锁和行级锁。

表级锁

MySQL中锁定粒度最大的一种锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。其锁定粒度最大,触发锁冲突的概率越高,并发度最低,MyISAM和InnoDB引擎都支持表级锁。

行级锁

Mysql中锁定粒度最小的一种锁,只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。

虽然使用行级锁具有粒度小、并发高等特点,但是表级锁在某些场景下也是必需的。

事务更新大表中的大部分数据时直接使用表级锁效率更高,避免频繁加行级锁。

事务比较复杂,使用行级锁很可能会导致死锁导致回滚。

锁的兼容性

按照是否兼容来分类,表级锁和行级锁可以再细分为共享锁和排它锁。

共享锁

共享锁(Share Locks,简记为S锁)又称为读锁。其它事务可以并发地读取数据,可以再加共享锁,但任何事务都不能获取数据上的排它锁,直至已经释放所有共享锁。

排它锁

排它锁(Exclusive lock,简记为X锁)又称为写锁。若事务对数据对象加上了排它锁,则只允许该事务对数据对象进行读取和修改,其它事务不能再对数据对象加任何类型的锁,直到该事务释放对象上的排它锁。在更新操作(INSERT、UPDATE 或 DELETE)过程中始终应用排它锁。

意向锁

为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁

意向共享锁(IS)

表示事务准备给数据行加入共享锁,事务在给一个数据行加共享锁之前必须先取得该表的IS锁。

意向排它锁(IX)

表示事务准备给数据行加入排它锁,事务在给一个数据行加排它锁之前必须先取得该表的IX锁。

意向锁的作用

MySQL中表锁和行锁共存,若不引入意向锁,该如何判断是否锁冲突呢?

假设事务T要对表T1加X锁,那就必须要判断T1表下每一个数据行是否加了S锁或者X锁。这样做的效率会非常低,需要对整个表进行遍历。在引入意向锁之后情况变得简单了。

假设事务T要对表T1加X锁,在这之前假设已经有事务A对数据行R加了S锁,那么此时表上已经有IS锁了(事务在给一个数据行加S锁之前必须先取得该表的IS锁)。由于X锁和IS锁冲突,所以事务T需要等待锁操作完成。这样就省去了遍历的操作,提高了冲突判断效率。

注意事项

意向锁是表锁,表示的是一种意向,仅仅表示事务正在读或写某一行记录,在真正加行锁时才会判断是否冲突。意向锁是InnoDB自动加的,不需要用户干预。

IX和IS是表锁,不会与行锁发生冲突,只会与表锁发生冲突

兼容情况

InnoDB的锁兼容情况如下所示。

锁算法

InnoDB主要实现了三种行锁算法。

Record Lock

记录锁,锁定一个行记录

Gap Lock

间隙锁,锁定一个区间

Next-Key Lock

记录锁+间隙锁,锁定行记录和区间

Next-Key Lock

Gap Lock和Next-Key Lock是为了解决幻读问题。

我们知道MVCC里面Repeated Read级别是快照读,read view是在执行事务中第一条select语句的瞬间创建,后续所有的select都是复用这个对象,所以能保证每次读取的一致性。可是这并不能确保就不会出现幻读问题了,仍然可能在执行insert/update时遇到幻读现象,因为SELECT 不加锁的快照读行为是无法限制其他事务对新增重合范围的数据的插入的。可能会出现这样的情况,select出了2条记录,update的时候却返回了3个成功结果。

InnoDB通过间隙锁来锁定区间间隔,避免其它事务在这个区间内插入其它数据导致出现幻读现象。

在MySQL的规范里面RR事务级别是可能出现幻读的,InnoDB通过间隙锁避免了这种情况。这个实现和规范有所差别。另外,Next-Key Lock是Repeated Read级别才会有的,在Read Committed级别并不存在。

示例

假设表T1(id private key),一共有3条记录1、3、5,同时有两个事务在进行。

事务A在T2时刻查询的结果为5,由于使用select … for update语句,这会在区间(3,+∞)这个范围内加上Gap Lock,因此在这个区间内的插入都是不被允许的。所以T6时刻查询结果也是5,避免了幻读现象。事务B在T4时刻想插入4,这个属于(3,+∞)区间,因此写入会被阻塞,直到事务A结束。

在此我向大家推荐一个架构学习交流群。交流学习群号:938837867 暗号:555 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备

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

推荐阅读更多精彩内容