mysql中InnoDB事務(wù)隔離的記錄鎖、間隙鎖和臨鍵鎖
InnoDB默認(rèn)的事務(wù)隔離級(jí)別為可重復(fù)讀(Repeated Read, RR),我們當(dāng)下的所有介紹都是基于這個(gè)隔離級(jí)別為前提的。
- 記錄鎖(Record Locks):鎖定單一行記錄,InnoDB 使用記錄鎖來(lái)實(shí)現(xiàn)行級(jí)鎖,這樣允許多個(gè)事務(wù)并發(fā)訪問(wèn)不同的行。
- 間隙鎖(Gap Locks):InnoDB 的特性,用于鎖定一個(gè)范圍,但不包括實(shí)際的記錄。這主要用于防止幻讀(Phantom Reads)。
- 臨鍵鎖(Next-Key Locks):InnoDB 存儲(chǔ)引擎的一種鎖定機(jī)制,在執(zhí)行查詢語(yǔ)句時(shí),根據(jù)查詢條件所鎖定的一個(gè)范圍。這個(gè)范圍中包含有間隙鎖和記錄鎖。它的設(shè)計(jì)目的是為了解決幻讀(Phantom Reads)。
記錄鎖(Record Locks)
記錄鎖,它封鎖索引記錄,例如:
select * from table where id=5 for update;
它會(huì)在id=1的索引記錄上加鎖,以阻止其他事務(wù)插入,更新,刪除id=1的這一行。
需要說(shuō)明的是:
select * from table where id=5;
則是快照讀(SnapShot Read),它并不加鎖,快照讀可以參考作者這篇文章:數(shù)據(jù)庫(kù)系列:RR和RC下,快照讀的區(qū)別
間隙鎖(Gap Locks)
間隙鎖,它封鎖索引記錄中的間隔,或者第一條索引記錄之前的范圍,又或者最后一條索引記錄之后的范圍。
延續(xù)上面的那個(gè)例子繼續(xù)演示:
# 表結(jié)構(gòu) table (Id PK, Name , Company); # 表中包含四條記錄 5, Gates, Microsoft 7, Bezos, Amazon 11, Jobs, Apple 14, Elison, Oracle
執(zhí)行SQL語(yǔ)句如下:
select * from table
where id between 7 and 13
for update;
這樣的話,會(huì)封鎖數(shù)據(jù)的區(qū)間,以防止其他事務(wù)插入id=8的記錄。
假設(shè)沒(méi)有間隙鎖,則可能夠插入成功,而之前的select事務(wù),會(huì)發(fā)現(xiàn)檢索的結(jié)果集莫名多了一條記錄,即幻影數(shù)據(jù)。
所以間隙鎖主要目的用于防止幻讀(Phantom Reads),避免其他事務(wù)在間隔中插入數(shù)據(jù),導(dǎo)致 『不可重復(fù)讀』。
如果把事務(wù)的隔離級(jí)別降級(jí)為讀提交(Read Committed, RC),對(duì),就是互聯(lián)網(wǎng)最常用的隔離級(jí)別,間隙鎖則會(huì)自動(dòng)失效。
臨鍵鎖(Next-Key Locks)
臨鍵鎖(Next-Key Locks)是數(shù)據(jù)庫(kù)管理系統(tǒng)InnoDB中的一種重要鎖定機(jī)制。這種鎖是查詢時(shí)根據(jù)查詢條件鎖定的一個(gè)范圍,這個(gè)范圍包括間隙鎖和記錄鎖,左開(kāi)右閉,即不鎖住左邊界,但會(huì)鎖住右邊界。臨鍵鎖的主要設(shè)計(jì)目的是為了解決所謂的“幻讀”問(wèn)題。
# 左開(kāi)右閉 示例 (-infinity, 1] (1, 7] (7, 9] (9, +infinity]
依然沿用上面的例子,InnoDB引擎,RR隔離級(jí)別:
-- 創(chuàng)建一個(gè)示例表
CREATE TABLE users (
Id INT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
Company VARCHAR(255) NOT NULL,
);
-- 插入一些示例數(shù)據(jù)
INSERT INTO users (id, name, company) VALUES (1, 'Alice', 'ali');
INSERT INTO users (id, name, company) VALUES (2, 'Brand', 'tencent');
INSERT INTO users (id, name, company) VALUES (3, 'Charlie', 'baidu');
-- 開(kāi)始一個(gè)事務(wù),并使用臨鍵鎖查詢數(shù)據(jù)
START TRANSACTION;
SELECT * FROM users WHERE id > 1 FOR UPDATE;
-- 在另一個(gè)事務(wù)中嘗試插入新數(shù)據(jù),將會(huì)被阻塞直到第一個(gè)事務(wù)釋放鎖
START TRANSACTION;
INSERT INTO users (id, name, age) VALUES (4, 'David', 30);
COMMIT;
-- 第一個(gè)事務(wù)提交后,第二個(gè)事務(wù)可以繼續(xù)執(zhí)行插入操作
COMMIT;
臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read),在事務(wù)隔離級(jí)別為可重復(fù)讀的情況下,InnoDB存儲(chǔ)引擎默認(rèn)使用臨鍵鎖。這種鎖提供了一種有效的機(jī)制來(lái)保證在并發(fā)環(huán)境中數(shù)據(jù)的完整性和一致性。
如果把事務(wù)的隔離級(jí)別降級(jí)為RC,臨鍵鎖則也會(huì)失效。
總結(jié)
- InnoDB的索引與行記錄存儲(chǔ)在一起,MyISAM則是通過(guò)索引的地址查找到對(duì)應(yīng)的數(shù)據(jù)記錄,效率低一些
- InnoDB的聚集索引存儲(chǔ)行記錄,普通索引存儲(chǔ)PK,所以普通索引要查詢兩次
- 記錄鎖鎖定索引關(guān)聯(lián)的具體記錄
- 間隙鎖鎖定間隔,防止間隔中被其他事務(wù)插入
- 臨鍵鎖鎖定索引記錄+間隔,防止幻讀
- select...for update加鎖的幾種情況:
- 主鍵字段:加行鎖。
- 唯一索引字段:加行鎖。
- 普通索引字段:加行鎖。
- 主鍵范圍:加多個(gè)行鎖。
- 普通字段:加表鎖。
- 查詢空數(shù)據(jù):不加鎖。
- 行鎖與表鎖的區(qū)別
- 如果事務(wù)1加了行鎖,一直未釋放鎖,事務(wù)2操作相同記錄,會(huì)一直等待直至超時(shí)。
- 如果事務(wù)1加了表鎖,一直未釋放鎖,事務(wù)2無(wú)論操作哪一行記錄,都會(huì)一直等待直到超時(shí)
到此這篇關(guān)于mysql中InnoDB事務(wù)隔離的記錄鎖、間隙鎖和臨鍵鎖的文章就介紹到這了,更多相關(guān)InnoDB的記錄鎖、間隙鎖和臨鍵鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
CentOS 6.5下yum安裝 MySQL-5.5全過(guò)程圖文教程
在linux安裝mysql是一個(gè)困難的事情,yum安裝一般是安裝的mysql5.1,現(xiàn)在經(jīng)過(guò)自己不懈努力終于能用yum安裝mysql5.5了。下面通過(guò)兩種方法給大家介紹CentOS 6.5下yum安裝 MySQL-5.5全過(guò)程,一起學(xué)習(xí)吧2016-05-05
MySQL關(guān)聯(lián)查詢優(yōu)化實(shí)現(xiàn)方法詳解
在數(shù)據(jù)庫(kù)的設(shè)計(jì)中, 我們通常都是會(huì)有很多張表 , 通過(guò)表與表之間的關(guān)系建立我們想要的數(shù)據(jù)關(guān)系, 所以在多張表的前提下, 多表的關(guān)聯(lián)查詢就尤為重要,這篇文章主要介紹了MySQL關(guān)聯(lián)查詢優(yōu)化2022-11-11
在MySQL中按字符串中的數(shù)字排序的詳細(xì)教程
本文將詳細(xì)介紹如何在MySQL中利用正則表達(dá)式提取字符串中的數(shù)字并按這些數(shù)字進(jìn)行排序,以一個(gè)具體的例子來(lái)說(shuō)明,使得即使是數(shù)據(jù)庫(kù)操作的初學(xué)者也能輕松理解和應(yīng)用,需要的朋友可以參考下2024-07-07
mysql中數(shù)據(jù)統(tǒng)計(jì)的技巧備忘錄
mysql是常用數(shù)據(jù)庫(kù),對(duì)于數(shù)字操作相關(guān)的東西相當(dāng)方便,這篇文章主要給大家介紹了關(guān)于mysql中數(shù)據(jù)統(tǒng)計(jì)技巧的相關(guān)資料,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-05-05
MySQL出現(xiàn)莫名其妙的斷開(kāi)連接以及解決方案
這篇文章主要介紹了MySQL出現(xiàn)莫名其妙的斷開(kāi)連接以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11

