天天看點

14.2.2.5 幻象讀

所謂的幻象讀發生在事務當相同的查詢産生不同的結果集在不同的時間,比如

如果SELECT 執行兩次,但是第2次傳回和第一次傳回時不相等的,這個記錄稱為 幻象行。

假設 這裡有一個index 在child 表的id列,你需要讀和lock 所有的記錄 值大于100,

意向更新一些列在選擇的記錄後。

SELECT * FROM child WHERE id > 100 FOR UPDATE;

查詢掃描index 從第一個記錄 id是大于100開始。 如果表包含記錄有id值在90和102.

如果locks 設定在index records 在掃描範圍 不允許插入在gaps 區間(在這種情況下, gap 區間是90到102)

另外的會話是插入一個新的記錄到表 值為101.

如果你執行相同的SELECT 在相同的事務裡,你會看到一個一個新的記錄id=101(一個幻讀)

查詢傳回的結果。如果我把一組資料集稱為資料項,

新的幻象child 會違反事務的隔離機制,一個事務可以運作在它的事務期間資料沒有改變。

為了防止幻讀,InnoDB 使用一個算法稱為next-key locking 組合index-row locking 和gap locking.

InnoDB 執行row-level locking 以這樣的方式 當它搜尋或者掃描一個表的索引,

它設定共享的或者排它鎖 在index records 它遇到的。是以,row-level locks 實際是index-record locks.

是以,一個next-key lock 在一個index record locks 也影響”gap” 在那個index record.

也就是說,一個next-key lock 是一個Index-record lock 加上一個gap lock 在gap index record 之前。

如果一個會話有一個共享鎖或者排它鎖在記錄R,另外的會話不能插入一個新的index record 在這個區間

立即在R 順序前。

當InnoDB 掃描索引時,它可以鎖住區間在最後的記錄 在索引裡,就像前面發生的例子:

為了防止任何的插入 ,id值大于100, InnoDB設定的locks 包括一個lock 在區間。

你可以使用next-key locking 來應用一個唯一檢查在你的應用。

如果你讀你的資料在共享模式和不會看到重複對于一條你要插入的記錄,

你可以安全的插入你的記錄和知道next-key lock 設定在你的記錄的繼承者 在讀阻止任何其他插入一個重複值。