当前位置: 首页 > 后端技术 > Java

MySQL记录锁、间隙锁、键锁小案例演示

时间:2023-04-02 00:16:13 Java

产生间隙锁和next-key锁的前提是在RR隔离级别下。关于Mysql记录锁、gap锁、next-key锁的一些理论知识之前已经写过了。详情请参考这篇文章。本文详细讲解了MySQL的锁机制。这篇文章主要通过一个小案例来解释一下记录锁、间隙锁、next-key锁的更好理解。这里先给出结论,再用实际例子证明1、使用唯一索引查询等值语句时,如果该行数据存在,则不会产生间隙锁,但会产生记录锁。2、使用唯一索引查询等价值时,如果该行数据不存在,会产生间隙锁。3、当使用唯一索引对查询语句进行范围查询时,会对满足查询条件但不存在的数据产生间隙(gap)锁。如果查询存在,会产生一个记录锁,组合为键锁(next-key)锁。4、使用普通索引时,无论是锁定单条记录还是多条记录,都会产生间隙锁;5.如果没有索引,无论是对单条记录还是多条记录加锁,都会产生表锁;间隙锁会阻塞记录记录两个相邻键之间的空白区域,以防止其他事务在该区域插入、修改和删除数据。这是为了防止幻读;差距的范围?根据检索条件,向下找到最接近检索条件的记录值A作为左区间,向上找到最接近检索条件的记录值B作为右区间,即锁定间隙为(A,B]左开右闭接下来我们开始验证以上结论1.数据和环境准备1.创建表和数据CREATETABLE`t`(`id`intNOTNULLAUTO_INCREMENTCOMMENT'primarykey',`age`intNOTNULLCOMMENT'age',`mobile`intDEFAULTNULLCOMMENT'mobilenumber',`name`varchar(8)DEFAULTNULLCOMMENT'name',PRIMARYKEY(`id`),KEY`index_age`(`age`))ENGINE=InnoDBAUTO_INCREMENT=8DEFAULTCHARSET=utf8;id为主键(唯一索引),age为普通索引,mobile不索引,插入数据如下。测试前,我们先看一下t表中隐藏的空隙:,1](1,4](4,7](7,+supernum](其中supernum是数据库维护的最大值。为了保证gap锁左开右闭的原则。)2.关闭事务并默认提交mysql>SHOWVARIABLESLIKE'autocommit';+------------+--------+|Variable_name|Value|+--------------+--------+|自动提交|ON|+-------------+------+1rowinset(0.00sec)结果显示autocommit的值为ON,表示系统开启自动提交模式,在MySQL中可以使用SETautocommit语句来设置自动提交模式transaction,语法格式如下:SETautocommit=0|1|ON|OFF;取值说明:0和OFF:关闭事务自动提交,如果关闭自动提交,用户将一直处于某个事务,只有提交或回滚后,当前事务才会结束并开始新的事务。值为1,值为ON:启用事务自动提交。如果启用了自动提交,则每执行一条SQL语句,就会提交一次事务。二、唯一索引示例1、等价查询和数据存在示例TransactionA等价查询id=4,因为id为主键,等价查询中存在记录,所以只会对id=4的记录加A记录锁,不会加间隙锁。id=5的事务B的等效查询没有锁冲突,所以查询正常,不会阻塞。(如果事务B的等价查询id为4,会被阻塞,因为事务A加了记录锁)2、等价查询和数据的例子不存在Transaction一个等效查询id=5,因为查询记录不存在,所以不能加记录锁,但是会有一个(5,7]间隙锁事务B插入一条id=6的数据,因为上面有(5,7]的间隙锁,所以会被阻塞3.范围查询示例TransactionArangequeryid>4,那么会有一个(4,+supernum]next-key(下一个键)锁。事务B插入一条id=6的数据,因为上面有(4,+supernum]的next-key锁,所以会阻塞。如果事务B更新了id=7的记录,也会阻塞4.常用索引示例1、等效查询值Transaction等效查询age=4,因为age是普通索引,所以会生成一个临时键(next-key)锁(1,4]和(4,7),左开右闭。事务B插入一个id=6,age=6的数据,因为age值在上面面对key锁,在范围内,所以也会被阻塞。2、左开右闭原则根据上面的例子,如果事务B插入了一条id=6,age=1的数据,会不会被阻塞,因为根据左开右闭的原则,上面的age=1是开启的,所以应该可以正常插入。但其实真正练习之后,你会发现它也会被堵住。经过实践你会发现,所谓的左开右闭原则与主键id有关。上面事务A等效查询age=4,其当前主键id=4,上一条记录主键id=1,下一条记录主键id=7。如果insertid<1,age在(1,7)范围内,是左闭右开的原则。即age=1可以插入,age=7会被阻塞。如果insert17,age在(1,7)范围内,就是左开右闭的原则。即age=1会被阻塞,age=7可以插入。不存在等价查询值的常见索引范围示例,这里不再举例。和上面类似,会产生间隙锁。4、无索引示例1、等效查询值Transaction等效查询mobile=8888884,因为mobile是无索引的,这个forupdate变成一个表级排他(X)锁。事务B因为事务A加了表级排它锁,其他事务不能进行任何增删改查。2.范围查询事务相当于查询mobile>8888884,因为mobile没有索引,所以这个forupdate成为表级排他(X)锁。事务B因为事务A加了表级排它锁,其他事务不能进行任何增删改查。本文由博客多发平台OpenWrite发布!