Mysql 行鎖 間隙鎖和next key鎖詳解

2021-10-06 09:54:58 字數 3504 閱讀 9284

一 、基本概念

innodb支援幾種不同的行級鎖,myisam只支援表級鎖

行鎖(record lock):對索引記錄加鎖。

間隙鎖(gap lock):鎖住整個區間,包括:區間裡具體的索引記錄,不存在的空閒空間(可以是兩個索引記錄之間,也可能是第乙個索引記錄之前或最後乙個索引記錄之後的空間)。

next-key鎖:行鎖和間隙鎖組合起來。

注意:如果檢索條件不是索引的話會全表掃瞄,則是表級鎖,不是行級鎖

二、行鎖(record lock)

對主鍵或者唯一索引進行增刪改或顯示的加鎖,innodb會加行鎖,如:

-- 顯示的加鎖

select * from people where id =

3for update;

update people set name=

'james' where id=

3

注意:

正常的查詢語句使用的是共享鎖。

對於顯示的加鎖或增刪改操作,條件判斷必須是精確匹配(也就是=) ,不能用》,<,between或like等範圍查詢方式,因為這樣會使行鎖變成next-key lock。

三、間隙鎖(gap lock)

官方文件描述:gap lock的唯一目的就是阻止其他事務插入到間隙中。gap lock可以同時存在,不同的事務可以同時獲取相同的gap lock,並不會互相衝突。gap lock也是可以顯示的被禁止的,只要將事務的隔離級別降低到 read committed。

對於間隙鎖,什麼叫鎖住不存在的空閒空間,舉個例子:

乙個表有id為1,2,3,5,6,9行資料,執行如下sql語句

select * from  people where id >

3 and id <

7for update;

這是乙個範圍檢索,innodb不僅會鎖住id為5和6兩行的資料,也會鎖住id為4(雖然該行並不存在)的紀錄。

四、next-key lock

官方文件描述:record lock+gap lock,如果乙個事務在記錄r上的某個索引有共享/互斥鎖,也會對其前面乙個範圍加鎖

鎖定的區域

根據索引會形成乙個個左開右閉的乙個區間,根據查詢的條件其所在的區間,並且包括其後的區間。

這裡給出乙個people表

idname

age1

james372

oven283

love

34如果age是索引的話,相關的區域有

(-無窮,28]

(28,34]

(34,37]

(37,+無窮)

如果執行如下語句:

select * from  people where age =

34for update;

那麼會鎖住(28,37]這麼範圍

如果執行如下語句:

select * from  people where age =

33for update;

那麼會鎖住(28,34)這麼範圍

間隙鎖的目的是為了防止幻讀,其主要通過兩個方面實現這個目的:

(1)防止間隙內有新資料被插入

(2)防止已存在的資料,更新成間隙內的資料

innodb自動使用間隙鎖的條件

(1)必須在repeatable read級別下

(2)檢索條件必須有普通索引(沒有索引的話,mysql會全表掃瞄,那樣會鎖定整張表所有的記錄,包括不存在的記錄,此時其他事務不能修改不能刪除不能新增)

注意:這裡的普通索引不包括主鍵索引和唯一索引,如果在這兩個索引下因為能精確檢索出結果,所以會使用record lock直接鎖定具體的行(範圍查詢除外)。

舉例: 對於表people

mysql> select * from people ;+--

--+-------

+| id | name |+--

--+-------

+|1| james ||2

| oven ||3

| love |+--

--+-------

+

時間順序

session a

session b

1begin;

2begin;

3select * from people where name=「oven」 for update ;(查詢到「oven」)

4update people set name=「zph」 where id=1; (此操作會被鎖住)

因為通過name索引執行select …for update會將(1,「james」)到(3,「love」)之間的資料都鎖住,所以第4步會被鎖住。

但是如果通過id主鍵索引來檢索

時間順序

session a

session b

1begin;

2begin;

3select * from people where id=2 for update ;(查詢到「oven」)

4update people set name=「zph」 where id=1; (此操作會被執行)

對於間隙鎖的許多例子可以看mysql中的幾種行鎖(間隙鎖、next-key鎖)

這個部落格中的顯示不了,可以通過下面的url訪問

五 、快照讀和當前讀

快照讀:通過mvcc實現,該技術不僅可以保證innodb的可重複讀,而且可以防止幻讀。但是他讀取的資料雖然是一致的,但是資料是歷史資料。

簡單的select操作(不包括 select … lock in share mode, select … for update)

當前讀:要做到保證資料是一致的,同時讀取的資料是最新的資料。innodb提供了next-key lock,即gap鎖與行鎖結合來實現。

select … lock in share mode

select … for update

insert

update

delete

總結在可重複讀隔離級別下並不能避免幻讀,如果要避免的話需要使用next-key lock。但是有了next-key lock以後,會導致併發插入的時候產生等待,所以這時候需要進行相關的優化。

參考mysql的鎖機制

mysql中的幾種行鎖(間隙鎖、next-key鎖)

mysql資料庫間隙鎖(mysql是如何解決幻讀的)

MySQL 表鎖 行鎖 間隙鎖

表鎖 表鎖有兩種模式 表共享讀鎖 表獨佔寫鎖 表共享讀鎖 讀鎖不會阻塞其他程序對同一表的讀操作,但阻塞寫操作,只有釋放鎖後其他程序才可以寫 表獨佔寫鎖 寫鎖會阻塞其他程序對同一表的讀和寫,只有寫鎖釋放後,其他程序才可以讀寫 簡而言之 讀鎖會阻塞寫,不阻塞讀 寫鎖阻塞讀和寫。行鎖 只鎖住某一行或多行的...

mysql間隙鎖 mysql間隙鎖

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

mysql 間隙鎖 mysql間隙鎖 轉

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