Mysql 等值查询时,加锁逻辑

发布于 2023-05-05  199 次阅读


目标:Mysql等值查询时,间隙锁是怎么工作的

工作示例

需要在事务隔离级别:可重复读 (URL:Mysql设置事务隔离级别方法)

使用两个窗口,运行Sql语句。(示例表/数据在下面)

TXA

查询t3表,id等于11并且加上排他锁(Exclusive Locks,简称X锁,写锁)


-- 窗口1
begin;
select * from t3 where id = 11 for update;

TXB

当执行了窗口1的命令后,会锁定间隙(10,20),所以窗口2的插入语句是不能在id为10~20之间插入任何id的,但是因为ID11不等于ID20,所以20的锁会被解除。


-- 窗口2
-- 插入id为12的数据,在窗口1不commit(提交)或者rollback(回滚)之前,是执行不成功的
insert into t3 value(12, 12, 12); 

-- ID20因为没有被锁定,所以是可以执行成功的
select * from t3 where id = 20 for update;

图表示例

首先锁定(10,20)间隙行记录ID20

主键索引主键↓间隙↓红色是被锁
(-♾️,0)0(0,10)10(10,20)20(20,30)30(30,40)40(40,50)50(50,+♾️)+♾️

↓因为查询的id是11不等于20,ID20这条行记录是不被需要的,所以ID20这条行记录会解锁

主键索引主键↓间隙↓红色是被锁
(-♾️,0)0(0,10)10(10,20)20(20,30)30(30,40)40(40,50)50(50,+♾️)+♾️

示例结构/数据

表结构


CREATE TABLE `t3` (
	`id` INT ( 11 ) NOT NULL,
	`c` INT ( 11 ) DEFAULT NULL,
	`d` INT ( 11 ) DEFAULT NULL,
	PRIMARY KEY ( `id` ),
KEY `c` ( `c` ) 
) ENGINE = INNODB;

数据


INSERT INTO t3
VALUES
	( 0, 0, 0 ),
	( 10, 10, 10 ),
	( 20, 20, 20 ),
	( 30, 30, 30 ),
	( 40, 40, 40 ),
	( 50, 50, 50 );

间歇性凌云壮志,持续性混吃等死