文章總共分爲五個部分: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]。