mysql 通过测试'for update',深入了解行锁、表锁、索引
条件
FOR UPDATE 仅适用于InnoDB存储引擎,且必须在事务区块(BEGIN/COMMIT)中才能生效。
mysql默认情况下每个sql都是单独的一个事务,并且是自动提交事务。
测试之前需要设置成非自动提交事务,不然无法模拟并发访问:
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
此修改只针对当前窗口有效,重新打开的新窗口依然是自动提交事务的
所以要就需要两个窗口,窗口a:非自动提交事务,用于for update操作;
窗口b:用于普通update操作。
测试
我们有一数据库 test1,有一张表testa ,有自增主键ID,name,id_card
表中有两条数据
mysql> select * from testa;
+----+-------+--------------------+
| id | name | id_card |
+----+-------+--------------------+
| 1 | wangb | 322343256564545754 |
| 2 | shuna | 320990348823998792 |
+----+-------+--------------------+
2 rows in set (0.00 sec)
mysql> desc testa;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(10) | NO | | NULL | |
| id_card | varchar(18) | YES | UNI | NULL | |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
1.只明确主键
有数据
在a窗口进行开启事务,对id为1的数据进行 for update,此时并没有commit;
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from testa where id = 1 for update;
+----+------+--------------------+
| id | name | id_card |