行级锁是 MySQL 中锁定粒度最细的一种锁,行级锁能大大减少数据库操作的冲突,行级锁分为共享锁和排他锁两种。
共享锁(Share Lock)
共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。
如果事务 T 对数据 A 加上共享锁后,则其他事务只能对 A 再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
用法
SELECT … LOCK IN SHARE MODE;
在查询语句后面增加 LOCK IN SHARE MODE,MySQL 就会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。
排他锁(Exclusive Lock)
排他锁又称写锁、独占锁,如果事务 T 对数据 A 加上排他锁后,则其他事务不能再对 A 加任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
用法
SELECT … FOR UPDATE;
在查询语句后面增加 FOR UPDATE,MySQL 就会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。
意向锁(Intention Lock)
意向锁是表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。InnoDB 中的两个表锁:
- 意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的 IS 锁;
- 意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的 IX 锁。
意向锁是 InnoDB 自动加的,不需要用户干预。
对于 INSERT、UPDATE 和 DELETE,InnoDB 会自动给涉及的数据加排他锁;对于一般的 SELECT 语句,InnoDB 不会加任何锁,事务可以通过以下语句显式加共享锁或排他锁。
共享锁:SELECT … LOCK IN SHARE MODE;
排他锁:SELECT … FOR UPDATE;