mysql一間隙鎖

2021-09-10 19:14:54 字數 1746 閱讀 1007

mysql innodb支援三種行鎖定方式:

預設情況下,innodb工作在可重複讀隔離級別下,並且以next-key lock的方式對資料行進行加鎖,這樣可以有效防止幻讀的發生。next-key lock是行鎖與間隙鎖的組合,這樣,當innodb掃瞄索引記錄的時候,會首先對選中的索引記錄加上行鎖(record lock),再對索引記錄兩邊的間隙(向左掃瞄掃到第乙個比給定引數小的值, 向右掃瞄掃瞄到第乙個比給定引數大的值, 然後以此為界,構建乙個區間)加上間隙鎖(gap lock)如果乙個間隙被事務t1加了鎖,其它事務是不能在這個間隙插入記錄的

舉個例子:

表task_queue

id           taskid

1              2

3              9

10            20

40            41

開啟乙個會話: session 1

sql> set autocommit=0;

取消自動提交

sql> delete from task_queue where taskid = 20;

sql> insert into task_queue values(20, 20);

在開啟乙個會話: session 2

sql> set autocommit=0;

取消自動提交

sql> delete from task_queue where taskid = 25;

sql> insert into task_queue values(30, 25);

在沒有併發,或是極少併發的情況下, 這樣會可能會正常執行,在mysql中, 事務最終都是穿行執行, 但是在高併發的情況下, 執行的順序就極有可能發生改變, 變成下面這個樣子:

sql> delete from task_queue where taskid = 20;

sql> delete from task_queue where taskid = 25;

sql> insert into task_queue values(20, 20);

sql> insert into task_queue values(30, 25);

這 個時候最後一條語句:insert into task_queue values(30, 25); 執行時就會爆出死鎖錯誤。因為刪除taskid = 20這條記錄的時候,20 --  41 都被鎖住了, 他們都取得了這乙個資料段的共享鎖, 所以在獲取這個資料段的排它鎖時出現死鎖。

間隙鎖在innodb的唯一作用就是防止其它事務的插入操作,以此來達到防止幻讀的發生,所以間隙鎖不分什麼共享鎖與排它鎖。另外,在上面的例子中,我們選擇的是乙個普通(非唯一)索引字段來測試的,這不是隨便選的,因為如果innodb掃瞄的是乙個主鍵、或是乙個唯一索引的話,那innodb只會採用行鎖方式來加鎖,而不會使用next-key lock的方式,也就是說不會對索引之間的間隙加鎖,仔細想想的話,這個並不難理解,大家也可以自己測試一下。

要禁止間隙鎖的話,可以把隔離級別降為讀已提交,或者開啟引數innodb_locks_unsafe_for_binlog

mysql間隙鎖 mysql間隙鎖

前面一文 mysql鎖 介紹了mysql innodb儲存引擎的各種鎖,本文介紹一下innodb儲存引擎的間隙鎖,就以下問題展開討論 1.什麼是間隙鎖?間隙鎖是怎樣產生的?2.間隙鎖有什麼作用?3.使用間隙鎖有什麼隱患?一 間隙鎖的基本概念 1.什麼叫間隙鎖 當我們用範圍條件而不是相等條件檢索資料,...

mysql 間隙鎖 mysql間隙鎖 轉

前面一文 mysql鎖 介紹了mysql innodb儲存引擎的各種鎖,本文介紹一下innodb儲存引擎的間隙鎖,就以下問題展開討論 1.什麼是間隙鎖?間隙鎖是怎樣產生的?2.間隙鎖有什麼作用?3.使用間隙鎖有什麼隱患?一 間隙鎖的基本概念 1.什麼叫間隙鎖 當我們用範圍條件而不是相等條件檢索資料,...

mysql間隙鎖 mysql的間隙鎖

最近學習了mysql的各種鎖,有點暈,打算通過文章的方式捋一捋。在學習了mvcc後,我就想,他已經很好的解決了併發讀寫了,但我也知道innodb提供了多種型別的鎖,所以很好奇這些鎖有什麼用,為什麼這些鎖的功能是mvcc做不到的?本文討論的都是rr級別下的鎖 我先建立乙個表,並插入幾行資料,如下圖 插...