MySQL数据库锁:Record Lock, Gap Lock 和 Next-Key Lock

InnoDB引擎 在 共享锁和排他锁 文章中,数锁我们详细分析了共享锁和排他锁在MySQL中是据库如何工作的,今天,数锁我们接着分析InnoDB引擎的据库 3种行锁。

在MySQL的数锁InnoDB引擎的行锁主要有三类:

Record Lock:记录锁,是据库在索引记录上加锁;Gap Lock:间隙锁,锁定一个范围,数锁但不包含记录;Next-key Lock:Next-key Lock = Gap Lock + Record Lock,据库它锁定了一个范围(Gap Lock实现),数锁并且锁定记录本身(Record Lock实现)

一、据库Record Lock

1.什么是数锁 Record Lock?

Record Lock,记录锁,据库它是数锁针对索引记录的锁,锁定的据库总是索引记录。在多用户数据库系统中,数锁多个事务可能会同时尝试读取或修改同一条记录,Record Lock确保只有一个事务能在某一时刻修改该记录,其他事务只能读取,或者在写锁释放后再进行修改。

2.举例说明

为了更好的说明Record Lock,我们以下面的顺序执行流来进行验证:

示例执行结果如下图:

通过上面的企商汇示例可以看出:

事务A(sessionA)对id=1加排他锁之后产生了记录锁事务B(sessionB)对id=1的update操作被阻塞了事务C(sessionC)可以查看到Record Lock

二、Gap Lock

1.什么是Gap Lock?

Gap Lock,间隙锁,它是一种行级锁,锁住两个索引记录之间的间隙,而不是实际的数据记录,由InnoDB隐式添加。

如下图:(1,3) 表示锁住记录1 和记录3 之间的间隙,这样记录2 就无法插入,间隙可能跨越单个索引值、多个索引值,甚至是空。

在InnoDB中,间隙锁是通过索引来实现的。这意味着间隙锁只能作用于索引,而不能直接作用于非索引列。当一个事务对某个索引列上的间隙加锁时,其他事务就无法在这个间隙中插入新的记录。

2.举例说明

为了更好的说明Gap Lock间隙锁,我们以下面的香港云服务器顺序执行流来进行验证:

示例执行结果如下图:

通过上面的示例执行结果可以看出:

事务A(sessionA)在加共享锁的时候产生了间隙锁(Gap Lock)事务B(sessionB)对间隙中进行insert/update操作,需要先获取排他锁(X),导致阻塞事务C(sessionC)通过show engine innodb status\G指令可以查看到间隙锁的存在。

需要说明,间隙锁只是锁住间隙内部的范围,在间隙外的insert/update操作不会受影响。

三、Next-Key Lock

1.什么是Next-Key Lock?

Next-Key Lock,称为临键锁,它是Record Lock + Gap Lock的组合,用来锁定一个范围,并且锁定记录本身锁,它是一种左开右闭的范围,可以用符号表示为:(a,b]。如下图:

2.举例说明

为了更好的说明Next-Key Lock,我们以下面的顺序执行流来进行验证:

示例执行结果如下图:

通过上面的示例执行结果可以看出:

事务A(sessionA)在加共享锁的时候产生了间隙锁(Gap Lock)事务B(sessionB)对间隙中进行insert操作,需要先获取排他锁(X),导致阻塞。亿华云事务C(sessionC)对间隙中进行update操作,需要先获取排他锁(X),导致阻塞。事务D(sessionD)通过show engine innodb status\G指令可以查看到间隙锁的存在。需要说明的,间隙锁只是锁住间隙内部的范围,在间隙外的insert/update操作不会受影响。

总结

Record Lock,Gap Lock和Gap Lock 3种锁是存在MySQL的InnoDB引擎的行锁,MyISAM引擎没有:

Record Lock:记录锁,是在索引记录上加锁;Gap Lock:间隙锁,锁定一个范围,但不包含记录,即(A,B);Next-key Lock:Next-key Lock = Gap Lock + Record Lock,它锁定了一个范围(Gap Lock实现),并且锁定记录本身(Record Lock实现),即(A,B];;

这 3种锁都是InnoDB引擎隐式添加的,目的是为了解决可重复读隔离级别下幻读的现象。

探索
上一篇:在Ubuntu中怎么安装JDK图文解析,对于很多不知道怎么操作的朋友可以参考本文,希望能给大家带来帮助!方法/步骤1,到Oracle官网下载相关的JDK2,假设jdk安装文件在桌面,我们指定的安装目录是:/usr/local/java 。可是系统安装后在/usr/local下并没有java目录,这需要我们去创建一个java文件夹3,打开终端(terminal)切换到桌面下,执行复制sudo cp jdk-6u30-linux-i586.bin /usr/local/java/安装jdk:切换到root用户下,(注:假如因忘记密码而认证失败,可以先修改root用户的密码,再执行,修改root用户密码如图)更改jdk-6u30-linux-i586.bin权限运行jdk-6u30-linux-i586.bin当看到下图情况时,说明你安装成功了。这时在/usr/local/java目录下就多了一个jdk1.6.0_30文件夹,可以查看一下注:假如因忘记密码而认证失败,可以先修改root用户的密码,再执行,修改root用户密码以上就是在Ubuntu中怎么安装JDK图文解析教程,大家看明白了吗?主要大家按照上面的步骤进行,即可成功安装JDK,希望能对大家有所帮助!
下一篇:探究常见电脑应用程序错误及解决方法(解决好用的电脑应用程序错误的关键技巧与方法)