偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官:什么是 Next-Key Lock?作用是什么?

數(shù)據(jù)庫 其他數(shù)據(jù)庫
Next-Key Lock 是 InnoDB 引擎行鎖加間隙鎖的組合,它鎖住的是一個前開后閉的區(qū)間,消除了 REPEATABLE READ 隔離級別下的幻讀問題。

Next-Key Lock 是 InnoDB 存儲引擎中非?;A(chǔ)也是非常重要的一個鎖。今天來聊一聊 Next-Key Lock。

首先我們回顧一下 MySQL 的事務(wù)隔離級別。

  • 串行化(Serializable):事務(wù)對數(shù)據(jù)讀寫都是串行的。
  • 可重復(fù)讀(Repeatable Read):事務(wù)執(zhí)行過程中,多次讀取同一行數(shù)據(jù),讀取結(jié)果一致。MySQL 默認隔離級別就是可重復(fù)讀。
  • 讀已提交數(shù)據(jù)(Read Committed):事務(wù)執(zhí)行過程中,如果有其他事務(wù)修改了數(shù)據(jù)并且提交事務(wù),當前事務(wù)可以讀取到最新提交的數(shù)據(jù)。
  • 讀未提交數(shù)據(jù)(Read Uncommitted):事務(wù)執(zhí)行過程中,可以讀取到其他事務(wù)未提交的數(shù)據(jù)。

可重復(fù)讀隔離級別解決了幻讀問題,而解決的方式就是通過 MVCC 和 Next-Key Lock。

幻讀:同一事務(wù)內(nèi)多次查詢同一范圍內(nèi)的數(shù)據(jù),因其他事務(wù)插入或刪除符合條件的數(shù)據(jù),導(dǎo)致事務(wù)在后面讀取到的結(jié)果集不一樣,像產(chǎn)生了幻覺。

介紹

Next-Key Lock 是間隙鎖(gap lock)和行鎖(index-record lock)的組合。

  • 行鎖: 鎖定索引中的某一條具體記錄。
  • 間隙鎖: 鎖定索引記錄之間的間隙,它鎖定的是一個范圍,這個范圍內(nèi)不存在數(shù)據(jù)。例如,如果鎖定了 (10, 20) 這個范圍,那其他事務(wù)就不能在這個范圍內(nèi)插入新記錄。

一個 Next-Key Lock,也就是行鎖加上該行之前的間隙鎖,因此,它鎖定的是一個前開后閉區(qū)間。

我們假設(shè)有一張表 t,包含(id,a,b)3 個字段,其中 id 是主鍵,字段 a 上面有普通索引,字段 b 沒有索引。建表語句如下:

CREATE TABLE `t` ( 
`id` int(10) NOT NULL, 
`a` int(10) DEFAULT NULL, 
`b` int(10) DEFAULT NULL, 
PRIMARY KEY (`id`), 
KEY `idx_a` (`a`)) ENGINE=InnoDB;

表中有 4 條記錄,分別(5,5,5),(10,10,10),(15,15,15),(20,20,20),那如果執(zhí)行下面語句:

select * from t where id = 7 for update;

這樣會對 id= 10 的記錄加 Next-Key Lock,鎖定的是 (5, 10] 這個區(qū)間,也就是說,除了鎖住 id = 10 這條記錄(行鎖),同時間隙鎖鎖住了 5 和 10 之間的間隙(5,10)。

而如果執(zhí)行下面這條 SQL,則會對整張表加 Next-Key Lock,因為字段 c 沒有索引,新插入的數(shù)據(jù)都可能包含 c = 6。加鎖后,形成 5 個范圍:

select * from t where c = 6 for update;

圖片圖片

加上了 Next-Key Lock,可以阻止其他事務(wù)在被鎖定的間隙中插入新的記錄,從而保證了當前事務(wù)中多次執(zhí)行相同查詢時,不會有新的記錄查出來,解決了幻讀問題。

在可重復(fù)隔離級別下,執(zhí)行下面幾個 SQL 時,都可能會對掃描過程中訪問到的記錄加 Next-Key Lock:

SELECT * from t where id =xxx FOR UPDATE;//id 不存在
SELECT * from t where a =xxx FOR UPDATE;
SELECT * from t where b =xxx FOR UPDATE;
SELECT * from t where id BETWEEN 10 AND 20;
SELECT * from t where id =xxx LOCK IN SHAREMODE;
UPDATE t set b = xxx where id = yyy;
DELETE from t where id = yyy;

非唯一索引和無索引的字段,都可能會匹配多條記錄,所以會加 Next-Key Lock。

那如果查詢的 id 存在,還會加 Next-Key Lock 嗎? 比如上面的表,執(zhí)行 SQL:

SELECT * from t where id = 10 for update;

答案是不會加 Next-Key Lock,這個時候 Next-Key Lock 退化成了行鎖。

查詢語句符合下面三個條件時,Next-Key Lock 會退化成行鎖:

  1. 查詢使用的是唯一索引;
  2. SQL 條件是等值匹配(比如 WHERE unique_key = X);
  3. 掃描到的記錄確定存在。

如果上面 3 個條件有一個不符合 ,都會加 Next-Key Lock。

另一點,雖然 Next-Key Lock 是前開后閉區(qū)間,如果索引上等值查詢向右遍歷到最后一個值不滿足等值條件,則退化為間隙鎖。比如執(zhí)行下面 SQL:

SELECT * from t where id = 8 for update;

Next-Key Lock 退化為間隙鎖,加鎖范圍是(5,10)。id = 10 的這條記錄不影響其他事務(wù)修改操作。

優(yōu)缺點

優(yōu)點:解決了 REPEATABLE READ 隔離級別下幻讀問題,有效保證了數(shù)據(jù)一致性。

缺點: 增加了鎖的粒度,一定情況下會降低并發(fā)性能,并增加死鎖發(fā)生的概率。因為多個事務(wù)可能以不同的順序請求對重疊的間隙加鎖,很容易造成死鎖。

下面是一個死鎖的案例,事務(wù) A 準備插入一條(8,8,8)的記錄,事務(wù) B 準備插入一條(9,9,9)的記錄,其他他們相互不影響,但加了 Next-Key Lock,就容易造成死鎖。

事務(wù) A

事務(wù) B

select * from t where id = 8 for update;



select * from t where id = 9 for update;


insert into t values(9,9,9);

insert into t values(8,8,8);


這樣兩個事務(wù)都會加(5,10)這個間隙鎖,最終相互等待,形成死鎖。

為什么兩個事務(wù)都可以加上間隙鎖,因為間隙鎖之間不會沖突。

總結(jié)

Next-Key Lock 是 InnoDB 引擎行鎖加間隙鎖的組合,它鎖住的是一個前開后閉的區(qū)間,消除了 REPEATABLE READ 隔離級別下的幻讀問題。理解 Next-Key Lock 要把握兩點:

  1. 可重復(fù)隔離級別下才會生效;
  2. 鎖住一個前開后閉的區(qū)間,但一定條件下可能退化成行鎖或者間隙鎖。
責(zé)任編輯:武曉燕 來源: 君哥聊技術(shù)
相關(guān)推薦

2021-06-05 18:02:20

MySQL加鎖范圍

2021-07-06 07:27:45

React元素屬性

2021-03-01 12:40:02

JavaserialVersi代碼

2021-06-08 09:41:26

MySQL加鎖范圍

2022-02-18 11:06:12

首席技術(shù)官技術(shù)人工智能

2022-04-29 11:39:28

MySQL幻讀Gap Lock

2021-09-07 10:44:33

Java 注解開發(fā)

2024-06-12 14:03:31

MySQLInnoDB

2025-03-05 00:01:00

ReduxReact

2025-04-24 10:56:01

MySQLInnoDB數(shù)據(jù)庫鎖

2025-03-05 02:10:00

2025-09-01 09:05:00

2023-12-06 09:10:28

JWT微服務(wù)

2022-09-29 07:30:57

數(shù)據(jù)庫索引字段

2021-12-08 06:53:29

面試動態(tài)代理

2024-02-22 15:36:23

Java內(nèi)存模型線程

2025-08-04 08:05:28

2025-07-15 02:15:00

MySQL索引回表

2009-07-07 16:38:36

ServletCont

2021-02-19 10:02:57

HTTPSJava安全
點贊
收藏

51CTO技術(shù)棧公眾號