InnoDB行鎖時通過給索引上的索引項加鎖來實現的,Oracle時通過在數據塊中相對應數據行加鎖來實現。
InnoDB這種行鎖實現特點意味着,只有通過索引條件檢索條件數據,InnoDB才使用行鎖,否則InnoDB將使用表鎖。
行鎖的三種算法
Record Lock :單個記錄上的鎖
鎖總會鎖住索引記錄,鎖住的時key。如果InnoDB存儲引擎表在建立的時候沒有設置任何一個索引,那么這時InnoDB會使用隱式的主鍵進行鎖定。
Gap Lock:間隙鎖,鎖定一個范圍,但不包含記錄本身
鎖定索引記錄間隙,確保索引記錄的間隙不變
間隙鎖時針對事務隔離級別為可重復讀或以上級別而配的
Gap Lock在InnoDB的唯一作用就是防止其他事務的插入操作,以此防止幻讀
Next-Key Lock:Gap Lock+Record Lock,鎖定一個范圍,並且鎖定記錄本身
在Next-Key Lock 算法下,InnoDB對於行的查詢都是采用這種鎖定的算法。可以有效的防止幻讀。
當查詢的索引含有唯一屬性時,InnoDB存儲引擎會對Next-Key Lock 進行優化,將其降級為 Record Lock,即僅鎖住索引本身,而不是范圍。
當查詢的索引為輔助索引時,默認使用Next-Key Locking技術進行加鎖,鎖定范圍是前一個索引到后一個索引之間范圍。
解決 Phantom Problem
在默認的事務隔離級別下,即REPEATABLE READ下,InnoDB存儲引擎次采用Next-Key Locking機制來避免Phantom Problem(幻讀問題).這點可能不同與其他的數據庫,比如Oracle數據庫,因為其可能需要在SERIALIZABLE的事務隔離級別下才能解決Phantom Problem。
Phantom Problem 是指在同一事務下,連續執行兩次同樣的SQL語句可能導致不同的結果,第二次SQL語句可能會返回之前不存在的行。
set session tx_isolation='read-committed'; 設置事務隔離級別為不可重復讀