欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL InnoDB中的鎖機(jī)制深入講解

 更新時(shí)間:2019年05月08日 10:54:43   作者:YoungChen  
這篇文章主要給大家介紹了關(guān)于MySQL InnoDB中鎖機(jī)制的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

寫在前面

數(shù)據(jù)庫(kù)本質(zhì)上是一種共享資源,因此在最大程度提供并發(fā)訪問(wèn)性能的同時(shí),仍需要確保每個(gè)用戶能以一致的方式讀取和修改數(shù)據(jù)。鎖機(jī)制(Locking)就是解決這類問(wèn)題的最好武器。

首先新建表 test,其中 id 為主鍵,name 為輔助索引,address 為唯一索引。

CREATE TABLE `test` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` int(11) NOT NULL,
 `address` int(11) NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `idex_unique` (`address`),
 KEY `idx_index` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;

INSERT 方法中的行鎖

可見,如果兩個(gè)事務(wù)先后對(duì)主鍵相同的行記錄執(zhí)行 INSERT 操作,因?yàn)槭聞?wù) A 先拿到了行鎖,事務(wù) B 只能等待直到事務(wù) A 提交后行鎖被釋放。同理,如果針對(duì)唯一索引字段 address 進(jìn)行插入操作,也需要獲取行鎖,圖同主鍵插入過(guò)程類似,不再重復(fù)。

但是,如果兩個(gè)事務(wù)都針對(duì)輔助索引字段 name 進(jìn)行插入,不需要等待獲取鎖,因?yàn)檩o助索引字段即使值相同,在數(shù)據(jù)庫(kù)中也是操作不同的記錄行,不會(huì)沖突。

Update 方法與 Insert 方法結(jié)果類似。

SELECT FOR UPDATE 下的表鎖與行鎖

事務(wù) A SELECT FOR UPDATE 語(yǔ)句會(huì)拿到表 test 的 Table Lock,此時(shí)事務(wù) B 去執(zhí)行插入操作會(huì)阻塞,直到事務(wù) A 提交釋放表鎖后,事務(wù) B 才能獲取對(duì)應(yīng)的行鎖執(zhí)行插入操作。

但是如果事務(wù) A 的 SELECT FOR UPDATE 語(yǔ)句緊跟 WHERE id = 1 的話,那么這條語(yǔ)句只會(huì)獲取行鎖,不會(huì)是表鎖,此時(shí)不阻塞事務(wù) B 對(duì)于其他主鍵的修改操作

輔助索引下的間隙鎖

先看下 test 表下的數(shù)據(jù)情況:

mysql> select * from test;
+----+------+---------+
| id | name | address |
+----+------+---------+
| 3 | 1 |  3 |
| 6 | 1 |  2 |
| 7 | 2 |  4 |
| 8 | 10 |  5 |
+----+------+---------+
4 rows in set (0.00 sec)

間隙鎖可以說(shuō)是行鎖的一種,不同的是它鎖住的是一個(gè)范圍內(nèi)的記錄,作用是避免幻讀,即區(qū)間數(shù)據(jù)條目的突然增減。解決辦法主要是:

  • 防止間隙內(nèi)有新數(shù)據(jù)被插入,因此叫間隙鎖
  • 防止已存在的數(shù)據(jù),在更新操作后成為間隙內(nèi)的數(shù)據(jù)(例如更新 id = 7 的 name 字段為 1,那么 name = 1 的條數(shù)就從 2 變?yōu)?3)

InnoDB 自動(dòng)使用間隙鎖的條件為:

  • Repeatable Read 隔離級(jí)別,這是 MySQL 的默認(rèn)工作級(jí)別
  • 檢索條件必須有索引(沒有索引的話會(huì)走全表掃描,那樣會(huì)鎖定整張表所有的記錄)

當(dāng) InnoDB 掃描索引記錄的時(shí)候,會(huì)首先對(duì)選中的索引行記錄加上行鎖,再對(duì)索引記錄兩邊的間隙(向左掃描掃到第一個(gè)比給定參數(shù)小的值, 向右掃描掃描到第一個(gè)比給定參數(shù)大的值, 以此構(gòu)建一個(gè)區(qū)間)加上間隙鎖。如果一個(gè)間隙被事務(wù) A 加了鎖,事務(wù) B 是不能在這個(gè)間隙插入記錄的。

我們這里所說(shuō)的 “間隙鎖” 其實(shí)不是 GAP LOCK,而是 RECORD LOCK + GAP LOCK,InnoDB 中稱之為 NEXT_KEY LOCK

下面看個(gè)例子,我們建表時(shí)指定 name 列為輔助索引,目前這列的取值有 [1,2,10]。間隙范圍有 (-∞, 1]、[1,1]、[1,2]、[2,10]、[10, +∞)

Round 1:

  • 事務(wù) A SELECT ... WHERE name = 1 FOR UPDATE;
  • 對(duì) (-∞, 2) 增加間隙鎖
  • 事務(wù) B INSERT ... name = 1 阻塞
  • 事務(wù) B INSERT ... name = -100 阻塞
  • 事務(wù) B INSERT ... name = 2 成功
  • 事務(wù) B INSERT ... name = 3 成功

Round 2:

  • 事務(wù) A SELECT ... WHERE name = 2 FOR UPDATE;
  • 對(duì) [1, 10) 增加間隙鎖
  • 事務(wù) B INSERT ... name = 1 阻塞
  • 事務(wù) B INSERT ... name = 9 阻塞
  • 事務(wù) B INSERT ... name = 10 成功
  • 事務(wù) B INSERT ... name = 0 成功

Round 3:

  • 事務(wù) A SELECT ... WHERE name <= 2 FOR UPDATE;
  • 對(duì) (-∞, +∞) 增加間隙鎖
  • 事務(wù) B INSERT ... name = 3 阻塞
  • 事務(wù) B INSERT ... name = 300 阻塞
  • 事務(wù) B INSERT ... name = -300 阻塞

InnoDB 鎖機(jī)制總結(jié)

參考資料

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • MySQL處理DB讀寫分離數(shù)據(jù)不一致問(wèn)題的方案

    MySQL處理DB讀寫分離數(shù)據(jù)不一致問(wèn)題的方案

    在互聯(lián)網(wǎng)中大型項(xiàng)目中,讀寫分離應(yīng)該是我們小伙伴經(jīng)常聽說(shuō)的,這個(gè)主要解決大流量請(qǐng)求時(shí),提高系統(tǒng)的吞吐量,本文給大家介紹了MySQL處理DB讀寫分離數(shù)據(jù)不一致問(wèn)題的方案,需要的朋友可以參考下
    2024-02-02
  • MYSQL Left Join優(yōu)化(10秒優(yōu)化到20毫秒內(nèi))

    MYSQL Left Join優(yōu)化(10秒優(yōu)化到20毫秒內(nèi))

    在實(shí)際開發(fā)中,相信大多數(shù)人都會(huì)用到j(luò)oin進(jìn)行連表查詢,但是有些人發(fā)現(xiàn),用join好像效率很低,而且驅(qū)動(dòng)表不同,執(zhí)行時(shí)間也不同。那么join到底是如何執(zhí)行的呢,本文就詳細(xì)的介紹一下
    2021-12-12
  • linux下mysql5.7.17最新穩(wěn)定版本安裝教程

    linux下mysql5.7.17最新穩(wěn)定版本安裝教程

    這篇文章主要為大家詳細(xì)介紹了linux上mysql5.7.17最新穩(wěn)定版本安裝教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • 淺談MySQL觸發(fā)器的原理以及使用

    淺談MySQL觸發(fā)器的原理以及使用

    這篇文章主要介紹了淺談MySQL觸發(fā)器的原理以及使用,觸發(fā)器的執(zhí)行不需要使用 CALL 語(yǔ)句來(lái)調(diào)用,也不需要手工啟動(dòng),只要一個(gè)預(yù)定義的事件發(fā)生就會(huì)被 MySQL自動(dòng)調(diào)用,需要的朋友可以參考下
    2023-05-05
  • MySQL易學(xué)易用之MYSQL不為人知的特性

    MySQL易學(xué)易用之MYSQL不為人知的特性

    MySQL易學(xué)易用,且附帶豐富的技術(shù)文檔,這二個(gè)因素使之被廣泛應(yīng)用。然而,隨著MySQL發(fā)展之迅速,即使一個(gè)MySQL老手有時(shí)也會(huì)為該軟件出其不意的功能感嘆。
    2011-01-01
  • MySQL 數(shù)據(jù)庫(kù)對(duì)服務(wù)器端光標(biāo)的限制

    MySQL 數(shù)據(jù)庫(kù)對(duì)服務(wù)器端光標(biāo)的限制

    從MySQL 5.0.2開始,通過(guò)mysql_stmt_attr_set() C API函數(shù)實(shí)現(xiàn)了服務(wù)器端光標(biāo)。服務(wù)器端光標(biāo)允許在服務(wù)器端生成結(jié)果集,但不會(huì)將其傳輸?shù)娇蛻舳耍强蛻舳苏?qǐng)求這些行。
    2009-03-03
  • 詳解MySQL多版本并發(fā)控制機(jī)制(MVCC)源碼

    詳解MySQL多版本并發(fā)控制機(jī)制(MVCC)源碼

    MVCC,即多版本并發(fā)控制(Multi-Version Concurrency Control)指的是,通過(guò)版本鏈維護(hù)一個(gè)數(shù)據(jù)的多個(gè)版本,使得讀寫操作沒有沖突,可保證不同事務(wù)讀寫、寫讀操作并發(fā)執(zhí)行,提高系統(tǒng)性能
    2021-06-06
  • 解析SQL Server 視圖、數(shù)據(jù)庫(kù)快照

    解析SQL Server 視圖、數(shù)據(jù)庫(kù)快照

    在程序開發(fā)過(guò)程中,任何一個(gè)項(xiàng)目都離不開數(shù)據(jù)庫(kù),這篇文章給大家詳細(xì)介紹SQL Server 視圖、數(shù)據(jù)庫(kù)快照相關(guān)內(nèi)容,需要的朋友可以參考下
    2015-08-08
  • MySQL的聯(lián)表查詢實(shí)現(xiàn)

    MySQL的聯(lián)表查詢實(shí)現(xiàn)

    數(shù)據(jù)通常分布在多個(gè)表中,為了獲取全面的信息,需要進(jìn)行聯(lián)表查詢,本文主要介紹了MySQL的聯(lián)表查詢實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-08-08
  • MySQL查看所有連接的客戶端ip方式

    MySQL查看所有連接的客戶端ip方式

    這篇文章主要介紹了MySQL查看所有連接的客戶端ip方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評(píng)論