首先要明确,如果不指定具体锁那么InnoDb引擎中update,delete,insert语句自动加排他锁的。
接下来说手动加锁的情况。
-
共享锁
后缀是LOCK IN SHARE MODE,例如:
/* 开启事务1 */
BEGIN;
/* 查询ID为1的数据并加上共享锁 */
SELECT * FROM `test` WHERE `id` = 1 LOCK IN SHARE MODE;
COMMIT;
- 多个事务的查询语句可以共用一把共享锁;
意义是多个事务都可以通过LOCK IN SHARE MODE给同一行数据加锁,但是只能SELECT。如果多个事务都LOCK IN SHARE MODE,那个谁删改谁死锁DEAD LOCK
- 如果只有一个事务拿到了共享锁,则该事务可以对数据进行 UPDATE DETELE 等操作;
第一个拿到锁的事务,可以删改,其他事务需要阻塞,前提是其他事务不会再次锁。
- 如果有多个事务拿到了共享锁,则所有事务都不能对数据进行 UPDATE DETELE 等操作
多个事务都LOCK IN SHARE MODE后,谁的事务需要删改,都会导致死锁,因为其他事务没有释放锁。
共享锁不阻塞共享锁,阻塞排它锁,使用场景:
确保多个事务查到最新的数据,并且事务期间不允许修改
2.排它锁
- 只有一个事务能获取该数据的排它锁;
- 一旦有一个事务获取了该数据的排它锁之后,其余事务对于该数据的操作将会被阻塞,直至锁释放。
排它锁会阻塞所有的排它锁和共享锁,使用场景:
- 确保某个事务查到最新的数据;
- 并且只有该事务能对数据进行修改、删除等操作。