事务 1:
begin;
update t_info set gender=1 where c_score > 85;
交易 2:
begin;
insert into t_info(c_id,c_class_no,c_score,c_name,gender) values (4,99,50,'gap',1);
事务 2 挂起,我不明白为什么。
前提条件:mysql Ver 14.14 Distrib 5.7.19-17
tx_isolation:REPEATABLE-READ
DROP TABLE IF EXISTS `t_info`;
CREATE TABLE `t_info` (
`c_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',
`c_class_no` int(11) NOT NULL DEFAULT '-1',
`c_score` int(11) NOT NULL DEFAULT '0',
`c_name` varchar(25) NOT NULL,
`gender` tinyint(4) NOT NULL COMMENT '0 male, 1 female',
PRIMARY KEY (`c_id`),
KEY `idx_name_score` (`c_name`,`c_score`),
KEY `idx_score` (`c_score`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `t_info`
VALUES
(1,1,60,'no1',0),
(2,2,60,'no2',0),
(3,3,60,'no3',0),
(6,4,78,'gap',1),
(7,5,95,'no5',0),
(10,8,87,'jianhaiqing',0),
(11,36,20,'no20',0),
(14,13,100,'no13',0),
(20,21,120,'no21',0),
(21,24,83,'no87-2',0);
事务 1:由于表行非常小,MySQL 本身进行了优化,因此将锁定整个表。
一件事:如果表格行足够大,例如。超过 1000 或其他。MySQL 会使用 idx_score 索引来扫描 c_score>85;
另:使用force index(idx_score)查询数据。然后,MySQL 只锁定二级索引 idx_score(也是 gaps)和对应的记录(不是记录 gap)。
我怀疑这是更新期间非常简单的表锁定。假设您在谓词列上没有索引,它将必须执行表扫描来评估
> 85
.添加索引
c_score
应该可以通过允许进行查找(或至少进行索引扫描)来解决此问题。