mysql中select for update的小测试
mysql的select for update语句中如果where没有命中会锁表,不过真实的场景是什么情况?这里简单进行一下测试。
版本:MySQL Docker Image 8.0.22-1.1.18。
测试场景如下:
1.使用索引且命中
2.使用索引没有命中
3.没有使用索引且命中
4.没有使用索引没有命中
5.使用了有索引和没有索引的且命中
6.使用了有索引和没有索引的没有命中
表结构如下:
create table dev.user
(
`id` int auto_increment,
`name` varchar(32),
`age` int,
primary key(`id`)
);
alter table user add index name_idx(`name`);
表中记录如下:
mysql> select * from user;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | tom | 18 |
+----+------+------+
1 row in set (0.00 sec)
1和2的场景,测试如下:
事务1
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where name = 'tom' for update;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | tom | 18 |
+----+------+------+
1 row in set (0.00 sec)
mysql> select * from user where name = 'bill' for update;
Empty set (0.00 sec)
事务2
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where name = "petter" for update;
Empty set (0.00 sec)
流程是事务1查询tom,事务2查询petter,事务1查询bill,可以看到都没有阻塞。
3和4的场景,测试如下:
事务1
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where age = 18 for update;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | tom | 18 |
+----+------+------+
1 row in set (0.00 sec)
事务2
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where age = 19 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
事务1
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where age = 18 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
事务2
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where age = 19 for update;
Empty set (0.00 sec)
流程是第一次事务1先查询age=18,事务2查询age=19,第二次事务2查询age=19,事务1查询age=18,可以看到两次都锁表了。
5和6的场景,测试如下:
事务1
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where name='tom' and age = 18 for update;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | tom | 18 |
+----+------+------+
1 row in set (0.00 sec)
事务2
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where name='petter' and age = 19 for update;
Empty set (0.00 sec)
流程是事务1查询tom和age=18,事务2查询petter和age=19,可以看到也都没有阻塞。

浙公网安备 33010602011771号