这样一张表 table(primary-key id, unique-key a, b) 类似于 update table set b= 'foo' where a = 'bar' 这样的语句
我同事说这样不行会导致锁表, 要改成 先 select id from table where a = 'bar' 然后再 update table set b= 'foo' where id = xx
我无语,这..有必要?
1 bransummer524 OP RR 级别 , 唯一索引等值查询,明明就是行锁 |
2 dongtingyue 2021-06-23 09:58:07 +08:00 半桶水晃荡,或者老古董。 |
3 dongtingyue 2021-06-23 10:11:25 +08:00 不过还是有区别的,只有 a 的话锁的不止一个。 |
4 Cy1 2021-06-23 10:47:01 +08:00 不会锁表吧,不是只会加 (a, b) 这棵索引树 全部 a 的间隙锁和行锁,以及 (id) 这棵主键索引树上对应 id 的行锁而已么 |
5 zibber 2021-06-23 11:49:50 +08:00 唯一索引如果 update 不指定 id, 如果在多个事务里操作不同行也会死锁, |
6 zibber 2021-06-23 11:53:23 +08:00 我遇到过 组合唯一索引使用 a, b 条件去 update 多个事务操作不同行就会死锁, 并不是正常理解的行锁 |
7 simonlu9 2021-06-23 12:35:53 +08:00 有可能吧,索引上范围都会锁,但不一定会锁表 |
![]() | 8 BQsummer 2021-06-23 12:49:29 +08:00 via Android 加了索引最差也是间隙锁,不会表锁 |
9 sunnyday123 2021-06-23 14:04:49 +08:00 unique a,b 已经和 id 一一对应了,和 where id 的条件也没啥区别,next-key lock 锁的范围也不是有别吧 |
10 sanestays 2021-06-23 18:21:32 +08:00 是会产生一个间隙锁的,有可能造成更新失败,可以自己试试, 建表: CREATE TABLE `aaaa` ( `id` int(11) NOT NULL AUTO_INCREMENT, `a` varchar(255) DEFAULT NULL, `b` varchar(255) DEFAULT NULL, `c` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `un` (`a`,`b`) USING BTREE ) ENGINE=InnoDB ; 数据: INSERT INTO `sane`.`aaaa`(`id`, `a`, `b`, `c`) VALUES (1, 'a', 'b', NULL); INSERT INTO `sane`.`aaaa`(`id`, `a`, `b`, `c`) VALUES (3, 'a', 'c', NULL); INSERT INTO `sane`.`aaaa`(`id`, `a`, `b`, `c`) VALUES (4, 'b', 'foo', NULL); INSERT INTO `sane`.`aaaa`(`id`, `a`, `b`, `c`) VALUES (5, 'c', 'b', NULL); 更新语句: 第一个:update aaaa set b= 'foo' where a = 'b'; 第二个:update aaaa set b= 'foo' where a = 'a'; 自己看下结果 |
11 bransummer524 OP @sanestays 可能我描述的不是很清晰,让你误解了, 唯一键只有 a 字段, b 只是一个普通字段 |
12 sanestays 2021-06-23 20:09:42 +08:00 @bransummer524 喔 我的问题 单个的话是会从 next-key lock 降级为 record key,和 where id 没有区别呀,没必要这样操作吧 |