Insert Intention Lock,中文我們也稱之為插入意向鎖。
這個可以算是對我們之前所講的 Gap Lock 的一個補充,關於 Gap Lock,如果還有小夥伴不懂,可以參考:。
我們之前已經有 Gap Lock 了,Gap Lock 可以幫我們在一定程度上解決幻讀問題,但是,之前的似乎有點問題。
假設我有如下一張表:
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`age` int(11) NOT NULL, PRIMARY KEY (`id`),
KEY `age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
登入後複製
id 是主鍵自增;age 是一個普通索引,現在表中有如下資料:
假設我想執行如下的插入 SQL:
begin;insert into user(username,age) values('wangwu',95);
登入後複製
注意,這個 SQL 執行了但是事務還沒有提交。
按照我們之前學習的關於 Gap Lock 的知識分析一下,此時間隙鎖的範圍是 (89,99),意思是這個範圍的 age 都不可以插入。
如果是這樣的話,小夥伴們會發現資料插入的效率可就太低了,很容易發生鎖衝突,那麼怎麼辦?
我們今天要介紹的插入意向鎖就是用來解決這個問題的。
我們來看看 MySQL 官網的介紹:
An insert intention lock is a type of gap lock set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6, respectively, each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting.
大致翻譯下一下就是這樣:
插入意向鎖是一種在 INSERT 操作之前設定的一種間隙鎖,插入意向鎖表示了一種插入意圖,即當多個不同的事務,同時往同一個索引的同一個間隙中插入資料的時候,它們互相之間無需等待,即不會阻塞(要是單純按照之前間隙鎖的理論,必須要等一個間隙鎖釋放了,下一個事務才可以往相同的間隙處插入資料)。假設有值為 4 和 7 的索引記錄,現在有兩個事務,分別嘗試插入值為 5 和 6 的記錄,在獲得插入行的排他鎖之前,每個事務使用插入意向鎖鎖定 4 和 7 之間的間隙,但是這兩個事務不會相互阻塞,因為行是不衝突的。
這就是插入意向鎖。
小夥伴們注意,鬆哥之前和大家聊 Gap Lock,說過這個是可重複讀(REPEATABLE READ)這個隔離級別下特有的產物,那麼現在 Insert Intention Lock 是一種特殊的 Gap Lock,當然也是在可重複讀這個隔離級別下生效。
接下來我們通過兩個個簡單的案例來演示一下插入意向鎖。
我們的表結構以及資料和第一小節一致。
首先我們在對談 A 中,執行如下程式碼:
現在對談 A 中的事務沒有提交。
接下來我們在對談 B 中,也執行一個插入操作:
我們發現對談 B 也可以正常執行,沒有發生阻塞。
這說明,兩個插入意向鎖之間是相容的,可以共存的。
我們再來看一個不相容的例子。
首先在對談 A 中執行如下 SQL 查詢 age 大於 80 的記錄,並新增排他鎖:
接下來在對談 B 中,執行如下程式碼插入一行資料:
小夥伴們看到,這個操作會被阻塞!阻塞的原因在於,插入意向鎖和排他鎖之間是互斥的。
趁著發生阻塞的這會,在對談 C 中,我們通過在前面文章中所使用的 show engine innodb status\G
指令,來檢視下加鎖的情況,重點看 TRANSACTION 節點:
在輸出的內容中,紅色框選中的地方,清楚的表明了插入意向鎖的存在。
總結一下:
插入意向鎖雖然名字中有意向二字,但實際上是一個特殊的間隙鎖。
插入意向鎖之間不互斥。
插入意向鎖和排他鎖之間互斥。
好啦,有問題歡迎留言討論。
相關推薦:《Linux視訊教學》
以上就是一文聊聊MySQL中的插入意向鎖的詳細內容,更多請關注TW511.COM其它相關文章!