記錄鎖、間隙鎖和臨鍵鎖
Record Lock
A record lock is a lock on an index record.
For example, SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;
prevents any other transaction from inserting, updating, or deleting rows where the value of t.c1 is 10.
記錄鎖鎖住的是索引記錄。如果使用索引作爲條件命中了記錄,那麼就是記錄鎖,被鎖住的記錄不能被別的事務插入相同的索引鍵值,修改和刪除。
我們在表中插入4條記錄,主鍵分別是1、4、7、10。
我們用主鍵或者唯一索引作爲條件等值查詢的時候,命中記錄就是加的記錄鎖,如:
select * from xx where id = 1;
命中記錄,所以id = 1這條記錄就加了記錄鎖。
Gap Lock
A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.
間隙鎖是鎖在索引之間或者第一個索引前面或者最後一個索引後面。
當我們使用索引無論是等值還是範圍查詢,沒有命中一條記錄時候,加的就是間隙鎖。
還是拿上面的例子,我們在表中插入4條記錄,主鍵分別是1、4、7、10。
圖中的範圍區間就會被鎖住,都是左開右開的區間。
select * from xx where id = 6 或者 select * from xx were id >4 and id < 7;
沒有命中任何一條記錄,會鎖住(4,7)區間,另一個事務插入id = 6則會阻塞;
select * from xx where id > 20沒有命中,會鎖住(10,正無窮),另一個事務插入id = 11會阻塞。
間隙鎖只在可重複讀隔離基本中存在。
Next-key Lock
A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.
當我們使用索引進行範圍查詢,命中了記錄的情況下,就是使用了臨鍵鎖,他相當於記錄鎖+間隙鎖。
兩種退化的情況:
-
唯一性索引,等值查詢匹配到一條記錄的時候,退化成記錄鎖。
-
沒有匹配到任何記錄的時候,退化成間隙鎖。
左開右閉區間,目的是爲了解決幻讀的問題。
select * from xx where id > 5 and id < 9;
上面的sql命中了id = 7的記錄,也包含了記錄不存在的區間,所以他鎖住(4,7]和(7,10]區間,在這區間,別的事務插入不了數據,所以解決了幻讀問題。