當同一個查詢在不同的時間產生不同的行集時,就會出現所謂的幻像問題,例如,如果執行了兩次SELECT,但是第二次回傳了第一次沒有回傳的行,那么該行就是一個“幻象”行,
假設在表child的id列上有一個索引,你想讀取并鎖定表中識別符號值大于100的所有行,并打算稍后更新所選行的某些列:
SELECT * FROM child WHERE id > 100 FOR UPDATE;
該查詢從id大于100的第一個記錄開始掃描索引,假設表包含id值為90和102的行,如果在掃描范圍內的索引記錄上設定的鎖沒有鎖定在間隙(在本例中是90到102之間的間隙),另一個會話可以向表中插入一個id為101的新行,如果要在同一個事務中執行相同的SELECT,則會在查詢回傳的結果集中看到一個id為101的新行(“幻象”),這就違反了事務的隔離原則,
為了防止出現幻象,InnoDB使用了一種名為next-key鎖定的演算法,它結合了索引行鎖和間隙鎖,InnoDB執行行級鎖的方式是這樣的:當它搜索或掃描一個表索引時,它會在遇到的索引記錄上設定共享鎖或排他鎖,因此,行級鎖實際上是索引記錄鎖,此外,索引記錄上的next-key鎖也會影響該索引記錄之前的“間隙”,也就是說,next-key鎖是索引記錄鎖加上索引記錄之前的間隙鎖,如果一個會話在一個索引中的記錄R上有一個共享鎖或排他鎖,另一個會話不能在緊接在索引順序中的R之前的間隙中插入新的索引記錄,
當InnoDB掃描一個索引時,它也可以鎖定索引中最后一條記錄之后的間隙,就像在前面的例子中發生的那樣:為了防止插入id大于100的表,InnoDB設定的鎖包括id值102后面的間隙鎖,

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/253457.html
標籤:MySQL
上一篇:事務隔離級別
