一、为查询添加显示的锁
SELECT …..FOR UPDATE;在一个事务中为查询操作加一个排它锁,其他事务可以执行查询操作但是查询操作不允许加任何锁,否则会发生阻塞;对于其他事务如果要更新当前事务查询的行,那么会发生阻塞的情况。
SELECT……LOCK IN SHARE MODE;在一个事物中对查询的行加共享锁,此时其他事务对同一行执行查询操作可以加共享锁,但是不允许加排他锁,同时,其他事务不能执行更新操作
二、为查询添加排它锁
CLIENT A开启一个事务并执行一个查询操作的同时对这个查询操作加排它锁(X锁)
mysql> start transaction;
Query OK, 0 rows affected (0.03 sec)
mysql> select phone from stu where id =1 for update;
+-------+
| phone |
+-------+
| 1 |
+-------+
1 row in set (0.03 sec)
CLIENT B开启一个事务,并对事务A查询的同一行执行了查询并添加一个排它锁(X锁)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select first_name from stu where id=1 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql>
这个时候出现了阻塞,但是我们可以看到,如果其他事务同时执行的是读操作而不加任何的锁,那么这个时候不会阻塞,但是如果执行时更新操作,那么就会发生阻塞
mysql> select phone from stu where id =1;
+-------+
| phone |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)
mysql> update stu set phone='12345' where id =1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
从上面的结果我们可以看到,当事务B执行查询操作但是不加锁时,不会发生阻塞,但是对事务A读锁定的行进行更新时,就会发生阻塞。
二、为查询添加共享锁
CLIENT A开启一个事务,并执行一此查询操作的同时对这个查询操作加共享锁(S 锁)
mysql> start transaction ;
Query OK, 0 rows affected (0.00 sec)
mysql> select phone from stu where id =1 lock in share mode;
+-------+
| phone |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)
CLIENT B执行一次查询操作并对查询的操作加共享锁(S 锁),然后再次执行了一次查询操作,不过添加的是排它锁(X 锁)。
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select phone from stu where id =1 lock in share mode;
+-------+
| phone |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)
mysql> select phone from stu where id =1 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
上面我们看到对于事务B执行查询操作并添加了一个共享锁,这个时候并没有发生阻塞现象;但是当我们执行一个查询操作并添加排他锁的时候,这个时候发生了阻塞。当然对于其他操作同样是会发生阻塞的
四、参考
《Mysql技术内幕-InnoDB引擎探析》