1
hjcpnr OP 补充一下
事务 1: select * from test where age = 80009 for update; 事务 2 ,需要阻塞等待事务 1 结束: select * from test where age = 80008 for update; 事务 3 ,不会阻塞,成功执行: update test set name ="haha" where age = 80008; 另外,如果把 age 的类型从 char 改成 int ,三个事务都不会互相阻塞 |
2
gumusu 2023-09-24 08:09:03 +08:00 via Android
字段类型不一致,隐式类型转换导致没走索引? explain 一下看看吧
|
3
mightybruce 2023-09-24 08:49:20 +08:00
select for update 百分百会加锁, 而且是悲观锁。
尽量少用 select for update |
4
mightybruce 2023-09-24 08:51:30 +08:00
看 mysql 文档,了解一下间隙锁、临键锁、记录锁的区别。
|
5
rekulas 2023-09-24 08:55:46 +08:00
没走索引,字符串你要用 age = '80008'
|
6
mightybruce 2023-09-24 09:05:54 +08:00
age 在 select 中 从 char 变为 int 发生了隐式转换,这个时候不会走索引
|
7
sansui3 2023-09-24 10:51:33 +08:00
@hjcpnr 你这个有问题吧,事务 3 也会被阻塞,我在本地试了一下(我的版本是 8.0.33 );为什么被阻塞,和其他人的结论是一样的,因为字段类型不一致所以其实锁的是全表,为什么显示事务 2 在等待 id=70031 的 record lock ,就是因为事务 2 也需要按“顺序”给全表的所有数据加锁,所以在给 70027 加锁的时候就在等待了,因为事务 1 已经给 70027 这条加索了。
|
8
jorneyr 2023-09-24 13:44:30 +08:00
MySQL 的自动类型转换非常不好,遇到过几次问题都是书写不规范导致了使用自动类型转换造成的。
|
9
uselessVisitor 2023-09-24 17:15:03 +08:00
@mightybruce rc 只有行锁吧
|
10
uselessVisitor 2023-09-24 17:15:34 +08:00
看看是否走了索引,走索引就是行锁,没走的话是表锁
|
11
katsusan 2023-09-24 20:37:30 +08:00
explain 一下就能看出来 age=80009 锁了全表.
```mysql mysql> explain select * from test where age = 80009 for update; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | test | NULL | ALL | idx_age | NULL | NULL | NULL | 3 | 33.33 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 3 warnings (0.00 sec) mysql> explain select * from test where age = '80009' for update; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | test | NULL | const | idx_age | idx_age | 40 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec) ``` |