1、共享鎖(Shared Locks S鎖)和獨占鎖(Exclusive Locks X鎖): 兩種標準的行級鎖
事務(wù)持有S鎖可以讀一行
事務(wù)持有X鎖可以update或delete一行
如果事務(wù)1拿到了R行的S鎖,那么事務(wù)2也可以同時立即拿到S鎖,但是事務(wù)2不能立即拿到X鎖
如果事務(wù)1拿到了R行的X鎖,那么事務(wù)2不能立即拿到任何類型的鎖,必須等待事務(wù)1釋放R行的X鎖
可以理解為X鎖與任何鎖沖突
2、意向鎖(Intention Locks)
innodb支持多粒度封鎖,允許行鎖和表鎖共存
意向鎖是表級鎖,指示稍后行所需要的鎖,有兩種:
一、共享意向鎖(IS),表示事務(wù)將在表的各個行上面加共享鎖 SELECT ... LOCK IN SHARE MODE
二、獨占意向鎖(IX),表示事務(wù)將在表的各個行上面加獨占鎖 SELECT ... LOCK FOR UPDATE
意向鎖法則:
①在一個事務(wù)獲取S鎖之前,必須先獲取IS鎖或者更強的鎖
②在一個事務(wù)獲取X鎖之前,必須先獲取IX鎖
四種鎖的兼容性如下:

如果一個事務(wù)需要的鎖與當前另一個事務(wù)持有的鎖不沖突,則該鎖會被成功授予,否則會等待沖突鎖釋放。意向鎖的主要目的是顯示某人正在鎖定行,或者要鎖定表中的行。
3、行鎖(Record Locks)
行鎖是對索引記錄的鎖定,比如SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE會阻止任何事務(wù)對
c1=10這一行進行insert、update、delete。就算表沒有建索引,行鎖也會鎖定索引記錄,InnoDB創(chuàng)建一個隱藏的聚簇索引,并使用此索引進行記錄鎖定。
4、區(qū)間鎖(Gap Locks)
區(qū)間鎖鎖定了多條索引記錄之間的內(nèi)容,或者在第一個之前或最后一個索引記錄之后的間隙,比如SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE,會阻止其他事務(wù)將值15插入到列t.c1中,無論是否已經(jīng)有了這個值。
使用了唯一索引的表,搜索唯一行則不會用到區(qū)間鎖(但是搜索條件中包含多個唯一索引字段的話還是可能會有鎖的)。比如SELECT * FROM child WHERE id = 100;,如果id擁有唯一索引,則不會加區(qū)間鎖,如果id沒有唯一索引,則會鎖住100之前的間隙。
沖突鎖可以發(fā)生在同一區(qū)間,如在同一個區(qū)間內(nèi),事務(wù)一可以有共享區(qū)間鎖,事務(wù)二可以持有獨占區(qū)間鎖。區(qū)間鎖的唯一目的就是防止其他事務(wù)插入?yún)^(qū)間。一個事務(wù)鎖住一段區(qū)間不影響另一個事務(wù)同時鎖定,共享區(qū)間鎖和獨占區(qū)間鎖沒有區(qū)別,他們都不會相互沖突,并且執(zhí)行著相同的功能。
可以通過將數(shù)據(jù)庫的隔離級別降低到READ_COMMITTED來指定明確區(qū)間鎖的間隙,在這些情況下,對于搜索和索引掃描的操作,不會使用到區(qū)間鎖,僅會用于外鍵約束檢查和重復(fù)鍵檢查。
當改變隔離級別到READ_COMMITTED后,mysql會評估WHERE查詢條件,并釋放不匹配行的行鎖。
5、Next-Key Locks
Next-Key Locks表示行鎖加這行記錄之前的區(qū)間鎖,如果一個事務(wù)在R行擁有S鎖或X鎖,另一個事務(wù)不在R行的索引記錄區(qū)間之前插入一條新的記錄。假設(shè)索引的值包含10,11,13,20,那么可能出現(xiàn)next-key lock的區(qū)間
(-∞, 10]
(10, 11]
(11, 13]
(13, 20]
(20, +∞)
在REPEATABLE_READ級別,innoDB會在查詢和索引掃描中使用Next-Key Lock,來防止幻讀
6、插入意向鎖(Insert Intention Locks)
插入意向鎖是插入之前觸發(fā)的一種區(qū)間鎖,這個插入意向鎖預(yù)示著多個事務(wù)可以插入同一個區(qū)間,并且不需要等待,除非他們插入的是區(qū)間中的同一行
7、AUTO-INC Locks
這是一種特殊的表鎖,事務(wù)在往數(shù)據(jù)庫中插入自增列的時候會觸發(fā)。