【发布时间】:2020-09-02 19:42:01
【问题描述】:
前提条件:
mysql version: 5.7.31
isolation level: RR
建表语句如下图:
CREATE TABLE `lockt` (
`id` int(11) NOT NULL,
`col1` int(11) DEFAULT NULL,
`col2` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `col1_ind` (`col1`),
KEY `col2_ind` (`col2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
有一些数据可供测试:
INSERT INTO `lockt` (`id`, `col1`, `col2`)
VALUES
(1,1,1),
(2,2,3),
(5,5,5),
(6,6,9),
(10,10,25),
(123,123,8),
(1007,10077,144),
(1008,1008,220),
(1019,1019,200),
(1020,1020,201),
(1111,1111,32),
(1234,1234,33);
在学习mysql中的gap lock的过程中,遇到了一个让我难以理解的案例:
在交易 1 中:
set autocommit=0;
begin;
select * from lockt;
select * from lockt where col2=25 lock in share mode;
然后,我开始另一个事务:
set autocommit=0;
begin;
select * from lockt;
update lockt set col2=66666 where col2 > 33;
但是我发现update语句被阻塞了。我认为SQL“select * from lockt where col2=25 lock in share mode”将申请共享锁,并在范围(9, 25],(25,32],但是范围(33,+∞]超出了这些范围,为什么第二笔交易仍然被阻止,这超出了我的预期。我很困惑为什么会这样。有什么特别的吗指出我误解的间隙锁定?任何可以帮助我解决此问题的人将不胜感激。
【问题讨论】:
-
几年前我问过MariaDB dev 的一个类似问题,这个问题有一个很好的解释。
-
建议包含
show engine innodb status中包含查询拥有的锁的部分。也许我的问题略有不同。
标签: mysql