在MySQL中,按照锁的粒度划分,可以分为行级锁,表级锁和页级锁。
行级锁
引擎:Innodb
- 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。
- 行级锁能大大减少数据库操作的冲突。
- 其加锁粒度最小,但加锁的开销也最大。
- 行级锁分为共享锁 和 排他锁。
特点
- 开销大,加锁慢;
- 会出现死锁;
- 锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
表级锁
引擎:MYISAM
- 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁。
- 它实现简单,资源消耗较少,被大部分MySQL引擎支持。
- 最常使用的MYISAM与INNODB都支持表级锁定。
- 表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。
特点
- 开销小,加锁快;
- 不会出现死锁;
- 锁定粒度大,发出锁冲突的概率最高,并发度最低。
页级锁
引擎:BDB引擎
- 页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。
- 表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。
- BDB支持页级锁
特点
- 开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
共享锁(读锁)
读取操作创建的锁。
- 其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。
- 如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。
- 获准共享锁的事务只能读数据,不能修改数据。
用法 SELECT … LOCK IN SHARE MODE;
在查询语句后面增加LOCK IN SHARE MODE,Mysql会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。
排它锁(写锁)
- 如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。
- 获准排他锁的事务既能读数据,又能修改数据。
用法 SELECT … FOR UPDATE;
在查询语句后面增加FOR UPDATE,Mysql会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。
意向锁
意向锁是表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。
InnoDB中的两个表锁:
意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁
意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。
参考资料
数据库的锁机制 http://www.hollischuang.com/archives/909
MySQL中的行级锁,表级锁,页级锁 http://www.hollischuang.com/archives/914
MySQL中的共享锁与排他锁 http://www.hollischuang.com/archives/923