概述
从对数据操作的粒度分:
- 表锁:操作时会锁住整张表
- 行锁:操作时会锁住当前操作行
从对数据操作的类型分:
- 读锁(共享锁):针对同一分数据,多个读操作可以同时进行而不会互相影响。
- 写锁(排它锁):当前操作没有完成之前,它会阻断其它写锁和读锁,不允许其它进行写或读。
不同的存储引擎对锁具有不同的支持情况:
存储引擎 | 表锁 | 行锁 |
MylSAM | 支持 | 不支持 |
InnoDB | 支持 | 支持 |
MEMORY | 支持 | 不支持 |
BDB | 支持 | 不支持 |
锁特性:
锁类型 | 特点 |
表锁 | 偏向MylSAM存储引擎,开销小,加锁快,不会出现死锁; 锁定粒度大,发生锁冲突的概率最高,并发度最低 |
行锁 | 偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁; 锁定粒度小,发生锁冲突的概率最低,并发度最高 |
表级锁更适合以查询为主,只有少量按索引条件更新数据的应用。
行级锁更适合有大量按索引条件并发更新少量不同数据,同时又有并查询的应用,如一些在线事务处理系统。
MyISAM 表锁
MyISAM 存储引擎只支持表锁
如何加表锁
MyISAM 在执行查询语句( SELECT )前,会自动给涉及的所有表加读锁,在执行更新操作( UPDATE 、 DELETE 、 INSERT 等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此,用户一般不需要直接用 LOCK TABLE 命令给 MyISAM 表显式加锁。
加读锁: lock table 表名 read ;
加写锁: lock table 表名 write ;
解锁:unlock tables;
注意:
我们在对一个表加上读锁之后,此时就不能再对其它表进行操作了,且只能对当前加锁的表进行读操作。读锁可以加多个,也就是多用户可以对同一表进行加读锁。
我们在对一个表加上写锁之后,此时就不能再对其它表进行操作了,且只能对当前加锁的表进行读或写操作。读锁只能加一个,加上写锁后,其它用户不能对这个表进行任何操作。
InnoDB行锁
InnoDB 实现了以下两种类型的行锁。
共享锁( s ):又称为读锁,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
排他锁( x ):又称为写锁,排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
行锁模式可以通过以下语句显示给某行加共享锁或排他锁。
共享锁 select * from 表名 where....lock in share mode
排他锁: select * from 表名 where....for update
注意:
对于 UPDATE 、 DELETE 和 INSERT 语句, InnoDB 会自动给涉及的行加排他锁;
对于普通 SELECT 语句, InnoDB 不会加任何锁