首頁  >  文章  >  資料庫  >  一文聊聊MySQL中的插入意向鎖

一文聊聊MySQL中的插入意向鎖

青灯夜游
青灯夜游原創
2022-12-21 20:56:302156瀏覽

這篇文章大家聊聊MySQL中的插入意向鎖,介紹一下什麼是插入意向鎖?為什麼需要插入意向鎖?希望對大家有幫助!

一文聊聊MySQL中的插入意向鎖

Insert Intention Lock,我們也稱為中文插入意向鎖。

這個可以算是對我們之前所講的Gap Lock 的一個補充,關於Gap Lock,如果還有小伙伴不懂,可以參考:記錄鎖、間隙鎖與Next-Key Locks

1. 為什麼需要插入意向鎖定

我們之前已經有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 都不可以插入。

如果是這樣的話,小夥伴們會發現資料插入的效率可就太低了,很容易發生鎖定衝突,那麼怎麼辦?

我們今天要介紹的插入意向鎖就是用來解決這個問題的。

2. 什麼是插入意向鎖定

我們來看看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 if if they at the not injid in the pame injem if. . 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 per gap between 4 and 7 with insert intention locks priortention oblock or or 片段) , but do not block each other because the rows are nonconflicting.

##大致翻譯下一下就是這樣:

插入意向鎖是一種在INSERT 操作之前設置的一種間隙鎖,插入意向鎖表示了一種插入意圖,即當多個不同的事務,同時往同一個索引的同一個間隙中插入數據的時候,它們互相之間無需等待,即不會阻塞(要是單純按照之前間隙鎖的理論,必須要等一個間隙鎖釋放了,下一個事務才可以往相同的間隙處插入資料)。假設有值為4 和7 的索引記錄,現在有兩個事務,分別嘗試插入值為5 和6 的記錄,在獲得插入行的排他鎖之前,每個事務使用插入意向鎖鎖定4 和7 之間的間隙,但是這兩個事務不會互相阻塞,因為行是不衝突的。

這就是插入意向鎖。

3. 實踐

小夥伴們注意,松哥之前和大家聊Gap Lock,說過這個是可重複讀(REPEATABLE READ)這個隔離等級下特有的產物,那麼現在Insert Intention Lock 是一種特殊的Gap Lock,當然也是在可重複讀取這個隔離等級下生效。

接下來我們透過兩個個簡單的案例來示範插入意向鎖。

3.1 案例一

我們的表格結構以及資料和第一小節一致。

首先我們在會話 A 中,執行以下程式碼:

現在會話 A 中的交易沒有提交。

接下來我們在會話 B 中,也執行一個插入操作:

#我們發現會話 B 也可以正常執行,沒有發生阻塞。

這說明,兩個插入意向鎖之間是相容的,可以共存的。

3.2 案例二

我們再來看一個不相容的範例。

首先在會話A 中執行如下SQL 查詢age 大於80 的記錄,並且加入排他鎖定:

接下來在會話B 中,執行如下程式碼插入一行資料:

小夥伴們看到,這個操作會被阻塞!阻塞的原因在於,插入意向鎖和排他鎖之間是互斥的。

趁著發生阻塞的這會,在會話C 中,我們透過在前面文章中所使用的show engine innodb status\G 指令,來查看下加鎖的情況,重點看TRANSACTION 節點:

在輸出的內容中,紅色方塊選取的地方,清楚的顯示了插入意圖鎖的存在。

4. 小結

總結一下:

  • 插入意向鎖定雖然名字中有意向二字,但實際上是特殊的間隙鎖。

  • 插入意向鎖定之間不互斥。

  • 插入意圖鎖定和排他鎖之間互斥。

好啦,有問題歡迎留言討論。

【相關推薦:mysql影片教學

#

以上是一文聊聊MySQL中的插入意向鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn