最近一段時間在准備新員工培訓的材料,本來打算介紹介紹概念就OK的,但是既然寫了事務的章節,就特別想介紹一下鎖,介紹了鎖,就忍不住想介紹一下Next-Key Lock。
大家知道,標准的事務隔離級別有READ UNCOMMITTED,READ COMMITTED,REPEATED READ和SERIALIZABLE。其中InnoDB默認實現了REPEATED READ級別,這個級別可以解決非一致性讀的問題,但是不能解決幻讀的問題,不過InnoDB采用了Next Key Lock算法,在該級別實現了幻讀保護。
至於什麼是幻讀,這個概念可以在官方文檔上找到答案,這裡就不再贅述了。
先看一個例子,按照下面的規則建表:
CREATE TABLE `test` ( `id` int(11) DEFAULT NULL, KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into test values (1), (3), (5), (8), (11);
注意,這裡id上是有索引的,因為該算法總是會去鎖住索引記錄。
現在,該索引可能被鎖住的范圍如下:
(-∞, 1], (1, 3], (3, 5], (5, 8], (8, 11], (11, +∞)
此時,按照下面表格中的順序開啟兩個Session,在Session B執行到第六步之前,都是可以成功的,第六步開始阻塞,第八步又可以正常執行。這樣,就能知道Session A中的SQL實際上鎖住了一個范圍,除了鎖住了8所在的(5, 8]區間,還同時鎖住了下一個區間:(8, 11],所以插入12就不在鎖定范圍內了。
這裡有個問題我還沒有想清楚,就是為什麼插入5還會被阻塞,如果誰知道請留言告知,謝謝,我自己也會找資料研究。
order Session A Session B 1 begin; 2 select * from test where id = 8 for update; 3 begin; 4 insert into test select 1; 5 insert into test select 4; 6 insert into test select 5; 7 insert into test select 9; 8 insert into test select 12;上面這個情況是輔助索引且不唯一的情況的鎖。如果是唯一索引呢?
如果將id列修改為主鍵,上面這個表格中,Session B第四和六步主鍵沖突就不說了,其他的步驟都可以執行成功, (5, 8], (8, 11]這兩個區間內的所有值(主鍵不沖突)都可以成功插入表中。這種現象的原因是,索引唯一,InnoDB會把鎖降級成Record Lock,只會鎖住一個記錄而已,這樣能很好的提升並發性。
利用Next Key Lock,InnoDB可以在REPEATABLE READ級別下,實現幻讀保護。
參考:http://www.cnblogs.com/zhoujinyi/p/3435982.html