mysql 版本是
8.0.26
并使用 REPEATABLE-READ
.
桌子:
create table test
(
id int auto_increment primary key,
a varchar(256) null,
b int null,
c int null,
create_time timestamp default CURRENT_TIMESTAMP null,
constraint uni_key unique (a, b, c)
);
初始数据:
insert into test(a,b,c) values ('a',1,1);
会议A | 会议B |
---|---|
开始; | 开始; |
插入测试(a,b,c)值('a',1,1); | |
错误 1062 (23000):重复条目 | 插入测试(a,b,c)值('b',2,3); |
(阻塞) |
会话 B 将被阻止,直到会话 A 提交。
查看下面的锁具信息
> SELECT ENGINE_LOCK_ID as Lock_Id,
ENGINE_TRANSACTION_ID as Trx_id,
OBJECT_NAME as `Table`,
INDEX_NAME as `Index`,
LOCK_DATA as Data,
LOCK_MODE as Mode,
LOCK_STATUS as Status,
LOCK_TYPE as Type
FROM performance_schema.data_locks;
+-----------------------------------------+--------+-------+---------+------------------------+------+---------+--------+
| Lock_Id | Trx_id | Table | Index | Data | Mode | Status | Type |
+-----------------------------------------+--------+-------+---------+------------------------+------+---------+--------+
| 140135522398208:1088:140135454819312 | 15656 | test | NULL | NULL | IX | GRANTED | TABLE |
| 140135522398208:23:5:27:140135454816400 | 15656 | test | uni_key | 'a', 1, 1, 64 | S | GRANTED | RECORD |
| 140135522398208:23:4:1:140135454817088 | 15656 | test | PRIMARY | supremum pseudo-record | X | GRANTED | RECORD |
+-----------------------------------------+--------+-------+---------+------------------------+------+---------+--------+
3 rows in set (0.01 sec)
我的疑问是为什么在联合索引是重复键后在主键上插入无限锁。
需要注意的是,如果SessionA中没有duplicate key,那么SessionB就可以执行成功,那么当抛出duplicate key的错误时,mysql是怎么做的,为什么
supremum pseudo-record
已为下一代密钥锁定。
参考:https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html
在此页面上搜索“supremum”了解详情。