文章总共分为五个部分:html
大而全版(五合一):InnoDB的锁机制浅析(All in One)sql
若是一个SQL语句要对二级索引(非主键索引)设置X模式的Record锁,InnoDB还会检索出相应的聚簇索引(主键索引)并对它们设置锁定。ui
SELECT ... FROM
是快照读取,除了SERIALIZABLE
的事务隔离级别,该SQL语句执行时不会加任何锁。code
SERIALIZABLE
级别下,SELECT
语句的执行会在遇到的索引记录上设置S模式的next-key锁。可是对于惟一索引,只锁定索引记录,而不会锁定gap。htm
S锁读取(SELECT ... LOCK IN SHARE MODE
),X锁读取(SELECT ... FOR UPDATE
)、更新UPDATE
和删除DELETE
这四类语句,采用的锁取决于搜索条件中使用的索引类型。对象
UPDATE ... WHERE ...
在搜索遇到的每条记录上设置一个独占的next-key锁,若是是惟一索引只锁定记录。
当UPDATE
修改聚簇索引时,将对受影响的二级索引采用隐式锁,隐式锁是在索引中对二级索引的记录逻辑加锁,实际上不产生锁对象,不占用内存空间。blog
例如
update test set code=100 where id=10;
执行的时候code=10
的索引(code是二级索引,见文中给出的建表语句)会被加隐式锁,只有隐式锁产生冲突时才会变成显式锁(如S锁、X锁)。即此时另外一个事务也去更新id=10
这条记录,隐式锁就会升级为显示锁。
这样作的好处是下降了锁的开销。索引
UPDATE
可能会致使新的普通索引的插入。当新的索引插入以前,会首先执行一次重复索引检查。在重复检查和插入时,更新操做会对受影响的二级索引记录采用共享锁定(S锁)。事务
DELETE FROM ... WHERE ...
在搜索遇到的每条记录上设置一个独占的next-key锁,若是是惟一索引只锁定记录。内存
INSERT
区别于UPDATE系列单独列出,是由于它的处理方式较为特别。
插入行以前,会设置一种插入意向锁,插入意向锁表示插入的意图。若是其它事务在要插入的位置上设置了X锁,则没法获取插入意向锁,插入操做也所以阻塞。
INSERT
在插入的行上设置X锁。该锁是一个Record锁,并非next-key锁,即只锁定记录自己,不锁定间隙,所以不会阻止其余会话在这行记录前的间隙中插入新的记录。
具体的加锁过程,见下一篇文章的第二章节(InnoDB的锁机制浅析(五)—InnoDB死锁场景)[http://www.javashuo.com/article/p-vxeyibie-gh.html]。