这样一张表 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 没有区别呀,没必要这样操作吧
|