關於InnoDB的Next-Key lock

    最近一段時間在準備新員工培訓的材料,本來打算介紹介紹概念就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還會被阻塞,如果誰知道請留言告知,謝謝,我自己也會找資料研究。

OrderSession ASession B
1begin;
2select * 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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章