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,可以看到也都没有阻塞。

posted @ 2021-03-02 11:05  latte575  阅读(251)  评论(0)    收藏  举报