MySQL InnoDB支持三种行锁定方式:

l   行锁(Record Lock):锁直接加在索引记录上面,锁住的是key。

l   间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙不变。间隙锁是针对事务隔离级别为可重复读或以上级别而已的。

l   Next-Key Lock :行锁和间隙锁组合起来就叫Next-Key Lock。

默认情况下,InnoDB工作在可重复读隔离级别下,并且会以Next-Key Lock的方式对数据行进行加锁,这样可以有效防止幻读的发生。Next-Key Lock是行锁和间隙锁的组合,当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录。

Gap Lock在InnoDB的唯一作用就是防止其他事务的插入操作,以此防止幻读的发生。

1、     行锁(Record Lock)

行锁锁定的是索引记录,而不是行数据,也就是说锁定的是key。

2、     间隙锁(Gap Lock)

例如:

create table test(id int,v1 int,v2 int,primary key(id),key `idx_v1`(`v1`))Engine=InnoDB DEFAULT CHARSET=UTF8;

该表的记录如下:

+----+------+------+

| id | v1   | v2   |

+----+------+------+

|  1 |    1 |    0 |

|  2 |    3 |    1 |

|  3 |    4 |    2 |

|  5 |    5 |    3 |

|  7 |    7 |    4 |

| 10 |    9 |    5 |

间隙锁(Gap Lock)一般是针对非唯一索引而言的,test表中的v1(非唯一索引)字段值可以划分的区间为:

(-∞,1)

(1,3)

(3,4)

(4,5)

(5,7)

(7,9)

(9, +∞)

假如要更新v1=7的数据行,那么此时会在索引idx_v1对应的值,也就是v1的值上加间隙锁,锁定的区间是(5,7)和(7,9)。同时找到v1=7的数据行的主键索引和非唯一索引,对key加上锁。

3、     后码锁(Next-Key Lock)

记录锁和间隙锁的结合,对于InnoDB中,更新非唯一索引对应的记录(在这里来说是更新v1字段的值),会加上Next-Key Lock。如果更新记录为空,就不能加记录锁,只能加间隙锁。

举个例子(事务隔离级别为MySQL默认的可重复读)

为什么TRANSACTION 2的insert操作会被阻塞,产生等待呢?这是因为TRANSACTION 2插入的v1值为6在TRANSACTION 1的锁定区间(5,9)内。而TRANSACTION 1插入的v1值不在TRANSACTION 2的锁定区间(5,7)内,故可以成功插入。不仅仅insert操作, update操作也一样会被锁住,从而锁等待超时。

4、     锁选择

1)、如果更新条件没有走索引,例如执行”update from t1 set v2=0 where v2=5;” ,此时会进行全表扫描,扫表的时候,要阻止其他任何的更新操作,所以上升为表锁。

2)、如果更新条件为索引字段,但是并非唯一索引(包括主键索引),例如执行“update from t1 set v2=0 where v1=9;” 那么此时更新会使用Next-Key Lock。使用Next-Key Lock的原因:

a)、首先要保证在符合条件的记录上加上排他锁,会锁定当前非唯一索引和对应的主键索引的值;

b)、还要保证锁定的区间不能插入新的数据。

3)、如果更新条件为唯一索引,则使用Record Lock(记录锁)。

InnoDB根据唯一索引,找到相应记录,将主键索引值和唯一索引值加上记录锁。但不使用Gap Lock(间隙锁)。

5、     间隙锁(Gap Lock)

加后码锁的时候,并没有锁住间隙两端的记录(这里的两端分别是5,9和5,7),那么两端的记录是可以更新的,但是如果更新两端的记录会影响到间隙锁,那么操作会被挂起,等待间隙锁释放。

看以下演示:

为什么在左侧值为4,右侧值为7的时候,有时候操作会被挂起,有时候操作不会挂起呢?解释如下:

当插入左侧值的时候,即插入v1=4的时候,要求插入的id值小于id=3的范围。当v1=4的记录有多条的时候,插入的id值要小于其中的最大id值。则可以成功插入;

当插入右侧值的时候,即插入v1=7的时候,要求插入的id值要大于id=7的范围。当v1=7的记录有多条的时候,插入的id值要大于其中的最小id值。则可以成功插入。

InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析相关推荐

  1. MySQL InnoDB锁机制全面解析分享

    写在前面:在设计新零售供应链wms(仓库管理系统)库存模块时,为了防止并发情况对库存的影响,查阅了一些资料,对InnoDB锁机制有了更全面的了解,在此做出分享,如有疏漏望不吝指正,愿共同进步!(此篇为 ...

  2. [转载] 数据库分析手记 —— InnoDB锁机制分析

    作者:倪煜 InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工 ...

  3. mysql innodb 的锁机制_Mysql之Innodb锁机制详解

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.关于事务我们之前有专题介绍,这里就着重介绍下它的锁机制. 总的来说,InnoDB按照不同的分类共有 ...

  4. Innodb 锁机制

    本文试图讲清楚 InnoDB 中存在的各种锁,以及它们锁定的区别. 前言 锁是数据库系统区别于文件系统的一个关键特性,锁机制用于管理对共享资源的并发访问.不同数据库和不同搜索引擎都可能有不同的锁机制, ...

  5. mysql innodb 锁_MySQL/InnoDB锁机制

    显式加锁 select ... lock in share mode:加 S 锁 select ... for update:加 X 锁 MySQL快照读和当前读 在一个支持MVCC并发控制的系统中, ...

  6. mysql锁机制——乐观锁、悲观锁;共享锁、排他锁、行表锁、间隔后码锁、MVCC 与 thinkphp的lock解析

    锁的引入 如果A有100元,同时对B.C转账,若处理是同时的,则此时同时读取A的余额为100元,在对两人转账后写回,A的余额不是0元而是50元.因此,为了防止这种现象的出现,要引入锁的概念,如只有在A ...

  7. MYSQL事务和INNODB下的锁机制

    文章目录 一 什么是事务 二 事务四大特性 原子性 一致性 隔离性 持久性 三 事务四大隔离级别 Read Uncommited(读未提交) Read Commited(读已提交) Repetable ...

  8. mysql innodb 并发 插入 慢_Innodb 锁机制——一次插入慢查询的排查

    慢查询日志中,发下有一条插入语句慢查询出现的概率比较高,一个简单插入需要消耗4-10s,很不寻常.附上插入语句,省略了一些字段 INSERT INTO `fc_pay_out_trade_log` ( ...

  9. Mysql INNODB引擎行锁的3种算法 Record Lock Next-Key Lock Grap Lock

    Mysql INNODB引擎行锁的3种算法 InnoDB存储引擎有3种行锁的算法,其分别是: □ Record Lock:单个行记录上的锁 Record Lock总是会去锁住索引记录,如果InnoDB ...

最新文章

  1. GitBook使用教程
  2. 最大子序列求和_最大子序列和问题
  3. 中国钢铁行业战略规划及项目建设动态分析报告2021-2027年
  4. android XMl 解析神奇xstream 五: 把复杂对象转换成 xml ,并写入SD卡中的xml文件
  5. 匹配yyyy-mm-dd日期格式的的正则表达式
  6. Dynamics 365的系统作业实体记录增长太快怎么回事?
  7. 后台得到webshell方法大汇总
  8. 表达式求值——数据结构严蔚敏C语言版栈数据结构课后练习
  9. python自带的解释器叫什么_什么是Python解释器?Python解释器有哪些?
  10. 信号处理常用matlab之数字滤波器及滤波函数
  11. MacBook IDEA 下载 安装 配置 使用
  12. 48页智慧城市大数据可视化平台建设方案
  13. 酷睿i5 10300h参数 i5 10300h处理器属于什么水平 i510300h相当于台式机
  14. 怎么写经济学论文的导言和文献综述
  15. linux常用命令 yum service ps
  16. 如何设置select-option的多项起始默认值
  17. pwm占空比的c语言编程详解,盘点占空比、PWM、GPIO三者含义及原理分析
  18. [R语言]{实例}车辆车架号VIN码校验函数
  19. python mse函数_Python 线性回归处理糖尿病数据 计算MSE等
  20. Activiti工作流引擎进阶【收藏可做笔记系列】

热门文章

  1. labview 重新启动后上次_还在为labview保存参数而苦恼吗?看看一个vi搞定全部
  2. mysql查询语句,int类型加引号居然也能查
  3. [Linux] 编写Dockerfile文件自动构建镜像
  4. Lambda表达式替代匿名方法
  5. poj1781In Danger(约瑟夫) 问题
  6. .NET自定义获得JSON的方法(System.Runtime.Serialization.Json)
  7. 设计模式--依然创建者
  8. 关于购买kbmMW 的好消息
  9. Sys.WebForms.PageRequestManagerServerErrorException(status code 500 OR 12031)
  10. storm能不能测试wadl_达尔优牧马人A960暴风Storm体验:轻而不飘,精准击打