最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL隔離級(jí)別和鎖機(jī)制的深入講解

 更新時(shí)間:2021年08月10日 17:30:04   作者:番茄炒蛋1  
這篇文章主要給大家介紹了關(guān)于MySQL隔離級(jí)別和鎖機(jī)制的相關(guān)資料,主要包括深入理解MySQL隔離級(jí)別和鎖機(jī)制使用實(shí)例、應(yīng)用技巧、基本知識(shí)點(diǎn)總結(jié)和需要注意事項(xiàng),需要的朋友可以參考下

簡述:

我們的MySQL一般會(huì)并發(fā)的執(zhí)行多個(gè)事務(wù),多個(gè)事務(wù)可能會(huì)并發(fā)的對(duì)同一條或者同一批數(shù)據(jù)進(jìn)行crud操作;可能就會(huì)導(dǎo)致我們平常所說的臟讀、不可重復(fù)讀、幻讀這些問題.

這些問題的本質(zhì)都是MySQL多事務(wù)并發(fā)問題,為了解決多事務(wù)并發(fā)問題,MySQL設(shè)計(jì)了鎖機(jī)制、MVCC多版本并發(fā)控制隔離機(jī)制、以及事務(wù)隔離機(jī)制,用一整套機(jī)制來解決多事務(wù)并發(fā)所出現(xiàn)的問題.

1. 事務(wù)的四大特性

特性 特點(diǎn)
Atomicity(原子性) 事務(wù)是不可分割的,其對(duì)數(shù)據(jù)的修改,要么全都執(zhí)行,要么全都不執(zhí)行
Consistency(一致性) 在事務(wù)提交的前后的狀態(tài)和數(shù)據(jù)都必須是一致的
Isolation(隔離性) 在多事務(wù)并發(fā)時(shí),保證事務(wù)不受并發(fā)操作影響的"獨(dú)立"環(huán)境執(zhí)行,這就意味著事務(wù)處理過程中的中間狀態(tài)對(duì)外部是不可見的,反之亦然
Druability(持久性) 指事務(wù)一旦提交,數(shù)據(jù)就持久化保存到磁盤中不會(huì)丟失

2.多事務(wù)并發(fā)帶來的問題

問題 現(xiàn)象 描述
臟讀 A事務(wù)正在對(duì)一條記錄做修改,在A事務(wù)完成并提交前,這條記錄的數(shù)據(jù)就處于不一致的狀態(tài)(有可能回滾也有可能提交),與此同時(shí),B事務(wù)也來讀取同一條記錄,如果不加控制,B事務(wù)讀取了這些"臟"數(shù)據(jù),并據(jù)此作進(jìn)一步處理,就會(huì)產(chǎn)生未提交的數(shù)據(jù)以來關(guān)系 一個(gè)事務(wù)中讀取到另一個(gè)事務(wù)尚未提交的數(shù)據(jù),不符合一致性要求
不可重復(fù)讀 一個(gè)事務(wù)在讀取某些數(shù)據(jù)后的某個(gè)時(shí)間,再次讀取以前讀過的數(shù)據(jù),卻發(fā)現(xiàn)其讀出的數(shù)據(jù)已經(jīng)發(fā)生了改變或某些記錄已經(jīng)被刪除了 一個(gè)事務(wù)中多次讀取的數(shù)據(jù)不一致,原因是收到其他事務(wù)已提交update的干擾,不符合隔離性
幻讀 一個(gè)事務(wù)按相同的查詢條件重新讀取以前查詢過的數(shù)據(jù),卻發(fā)現(xiàn)其他事務(wù)插入滿足其查詢條件的新數(shù)據(jù) 一個(gè)事務(wù)中多次讀取的數(shù)據(jù)不一致,原因是受其他事務(wù)已提交insert/delete的干擾,不符合隔離性

3.事務(wù)的隔離級(jí)別

臟讀、不可重復(fù)讀和幻讀,其實(shí)都是MySQL讀一致性問題,必須由數(shù)據(jù)庫提供一定的事務(wù)隔離機(jī)制來解決.

隔離級(jí)別 臟讀 不可重復(fù)讀 幻讀
Read uncommitted(讀未提交)
Read committed(讀已提交) ×
Repetatble read(可重復(fù)讀)(MySQL默認(rèn)) × ×
Serializable(串行化) × × ×

查看當(dāng)前數(shù)據(jù)庫的事務(wù)隔離級(jí)別:show variables like ‘tx_isolation';

設(shè)置事務(wù)隔離級(jí)別:set tx_isolation='隔離級(jí)別'

4.演示不同隔離級(jí)別出現(xiàn)的問題

mysql版本:5.7.34

涉及表:

兩個(gè)MySQL客戶端

客戶端A <===================> 客戶端B(下面每張圖片兩個(gè)客戶端皆以第一張圖命名為準(zhǔn)

讀未提交

1.1 設(shè)置事務(wù)隔離級(jí)別set tx_isolation=‘read-uncommitted';

1.2 客戶端A和客戶端B各開啟一個(gè)事務(wù),

1.3 客戶端A只做查詢,客戶端B對(duì)id = 1的記錄做修改;

1.4 再兩個(gè)事務(wù)都未提交的情況下,事務(wù)A讀到了事務(wù)B修改后的數(shù)據(jù)

1.5 一旦客戶端B的事務(wù)因?yàn)槟撤N原因rollback,那么客戶端A查詢到的數(shù)據(jù)其實(shí)就是臟數(shù)據(jù),不符合一致性的要求

讀已提交

2.1 設(shè)置隔離級(jí)別讀已提交:set tx_isolation=‘read-committed';

2.2 客戶端A和客戶端B各開啟一個(gè)事務(wù),

2.3 客戶端A只做查詢,客戶端B對(duì)id = 1的記錄做修改;

2.4 客戶端B未提交事務(wù)時(shí),客戶端A不能查詢客戶端B未提交的數(shù)據(jù),解決了臟讀的問題

2.5 當(dāng)客戶端B提交事務(wù)后,客戶端A再次對(duì)表進(jìn)行查詢,結(jié)果與上一步不一致,即產(chǎn)生了不可重復(fù)讀的問題,不符合隔離性

可重復(fù)讀

3.1 設(shè)置隔離級(jí)別可重復(fù)讀:set tx_isolation=‘repeatable-read';

3.2 客戶端A和客戶端B各開啟一個(gè)事務(wù),

3.3 客戶端B修改表中數(shù)據(jù)然后提交;

3.4 客戶端A查詢表中數(shù)據(jù),并未出現(xiàn)與上一步不一致的問題,解決了不可重復(fù)讀的問題

3.5 在客戶端A中執(zhí)行update account set balance = balance - 100 where id = 1;blance并未有變成800-100=700;而是使用客戶端B提交后的數(shù)據(jù)來算的,所以是600;數(shù)據(jù)的一致性并沒有被破壞;可重復(fù)讀的隔離級(jí)別下使用的是MVCC機(jī)制,select操作不會(huì)更新版本號(hào),是快照讀(歷史版本),保證同一事務(wù)下的可重復(fù)讀;insert/update/delete會(huì)更新版本號(hào),是當(dāng)前讀(當(dāng)前版本)保證數(shù)據(jù)的一致性

3.6 客戶端B重新開啟一個(gè)事務(wù)插入一條數(shù)據(jù)后提交

3.7 在客戶端A中重新查詢表數(shù)據(jù),并沒有出現(xiàn)客戶端B剛才新增的數(shù)據(jù),沒有出現(xiàn)幻讀

3.8 驗(yàn)證幻讀:在客戶端A中,對(duì)id = 4 的數(shù)據(jù)做修改;可以更新成功;再次進(jìn)行查詢就能查詢出客戶端B新增的數(shù)據(jù),出現(xiàn)幻讀問題,不符合隔離性

串行化

4.1 設(shè)置隔離級(jí)別串行化:set tx_isolation=‘serializable';

4.2 客戶端A和客戶端B各開啟一個(gè)事務(wù),

4.3 客戶端A先查詢表中id = 1的數(shù)據(jù)

4.4 在客戶端A事務(wù)未提交時(shí),客戶端B對(duì)表中id = 1 的數(shù)據(jù)做更新;由于客戶端A的事務(wù)并沒有提交,客戶端B的更新動(dòng)作將會(huì)阻塞至到客戶端A提交事務(wù)或者超時(shí),超時(shí)SQL報(bào)錯(cuò):Lock wait timeout exceeded; try restarting transaction

4.5 在客戶端B中更新id = 2 的數(shù)據(jù)卻可以成功,說明在串行化的隔離級(jí)別下,innodb的查詢也會(huì)被加上行鎖;

4.6 如果客戶端A執(zhí)行的是一個(gè)范圍查詢,那么該范圍內(nèi)的所有行包括每行記錄所在的間隙區(qū)間范圍(就算該行未被插入也會(huì)加鎖,這種是間隙鎖)都會(huì)被加鎖,此時(shí)如果客戶端B對(duì)該范圍內(nèi)的數(shù)據(jù)做任何操作都會(huì)被阻塞;所以就避免了幻讀;

4.7 串行化這種隔離級(jí)別并發(fā)性極低,所以再真實(shí)的開發(fā)很少會(huì)遇到,這也是MySQL為什么使用可重復(fù)讀作為默認(rèn)的隔離級(jí)別的重要原因

5.鎖機(jī)制

MySQL默認(rèn)的隔離級(jí)別是可重復(fù)讀,可是還是會(huì)出現(xiàn)幻讀問題;間隙鎖再某種情況下可以解決幻讀問題;

間隙鎖

概述:間隙鎖,鎖的就是兩個(gè)值之間的空隙.

假設(shè)表中數(shù)據(jù)如下:

那么間隙就有(4,10)、(10,15)和(15,正無窮)三個(gè)間隙;

1.1 設(shè)置隔離級(jí)別可重復(fù)讀:set tx_isolation=‘repeatable-read';

1.2 客戶端A和客戶端B各開啟一個(gè)事務(wù),

1.3 在客戶端A執(zhí)行update account set balance = 1000 where id > 5 and id < 13 ;

1.4 在客戶端A未提交的時(shí)候,客戶端B是沒有辦法對(duì)這個(gè)范圍包含的所有行記錄(包括間隙行記錄)以及行記錄所在間隙里執(zhí)行insert/update操作,即4<id<=15這個(gè)區(qū)間內(nèi)都無法修改數(shù)據(jù),id = 15 同樣不能修改;

1.5 間隙鎖只有在可重復(fù)讀的隔離級(jí)別下才會(huì)生效

臨建鎖

概述:臨建鎖是行鎖和間隙鎖的結(jié)合,想上面那個(gè)4<id<=15就屬于臨建鎖;

無索引行鎖會(huì)升級(jí)成為表鎖

3.1 客戶端A和客戶端B各開啟一個(gè)事務(wù),

3.2 在客戶端A執(zhí)行update account set balance = 1000 where name = ‘李四';

3.3 在客戶端A未提交的時(shí)候,客戶端B執(zhí)行update account set balance = 800 where id = 15 ;同樣會(huì)被阻塞至客戶端A提交或者超時(shí);

3.4 MySQL中的鎖主要是加載索引字段上,如果使用再非索引字段上,行鎖會(huì)升級(jí)成表鎖;

排他鎖

4.1 客戶端A和客戶端B各開啟一個(gè)事務(wù),

4.2 在客戶端A執(zhí)行select * from account where id = 1 for update ;

4.3 在客戶端A未提交的時(shí)候,客戶端B執(zhí)行update account set balance = 800 where id = 1 ;會(huì)被阻塞至客戶端A提交或者超時(shí);

結(jié)論:Innodb引擎實(shí)現(xiàn)了行鎖,雖然行鎖機(jī)制實(shí)現(xiàn)方面所帶來的性能損耗可能比表級(jí)鎖定會(huì)更高,但是再整體并發(fā)處理能力肯定要強(qiáng)于表級(jí)鎖;當(dāng)系統(tǒng)并發(fā)量高的時(shí)候,行級(jí)鎖和表級(jí)鎖相比就會(huì)有比較明顯的優(yōu)勢(shì);但是行級(jí)鎖使用起來也比表級(jí)鎖復(fù)雜,當(dāng)我們使用不當(dāng)?shù)臅r(shí)候,可能會(huì)使行鎖的性能不僅不比表級(jí)鎖的性能高,甚至可能會(huì)更差.

為什么行鎖鎖定的粒度小,開銷反而會(huì)比表級(jí)鎖的開銷大?

因?yàn)楸砑?jí)鎖只需要找到當(dāng)前表就可以進(jìn)行加鎖,行鎖的話需要對(duì)表中記錄進(jìn)行掃描,直至掃描到需要加鎖的行才可以進(jìn)行加鎖,所以行鎖的開銷是比表級(jí)鎖的開銷要來得大的.

真實(shí)開發(fā)情況下對(duì)鎖優(yōu)化的一些建議:

  • 合理使用索引字段加鎖,縮小鎖的范圍
  • 盡可能讓所有鎖都加到索引字段上,避免無索引行鎖升級(jí)成表鎖
  • 盡可能減少查詢范圍,避免間隙過大的間隙鎖
  • 盡可能低級(jí)別事務(wù)隔離
  • 盡可能控制事務(wù)大小,減少鎖定資源量,涉及事務(wù)加鎖的sql盡量放在事務(wù)最后執(zhí)行,減少加鎖的時(shí)間

總結(jié)

到此這篇關(guān)于MySQL隔離級(jí)別和鎖機(jī)制的文章就介紹到這了,更多相關(guān)MySQL隔離級(jí)別和鎖機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一臺(tái)服務(wù)器部署兩個(gè)獨(dú)立的mysql數(shù)據(jù)庫操作實(shí)例

    一臺(tái)服務(wù)器部署兩個(gè)獨(dú)立的mysql數(shù)據(jù)庫操作實(shí)例

    這篇文章主要給大家介紹了關(guān)于一臺(tái)服務(wù)器部署兩個(gè)獨(dú)立的mysql數(shù)據(jù)庫的相關(guān)資料,同一臺(tái)服務(wù)器裝兩個(gè)數(shù)據(jù)庫,可以通過虛擬化技術(shù)實(shí)現(xiàn),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • MySQL數(shù)據(jù)庫索引order?by排序精講

    MySQL數(shù)據(jù)庫索引order?by排序精講

    我們今天說的并不是大數(shù)據(jù)下該如何優(yōu)雅的排序,如何提升排序性能的問題,我們來仔細(xì)分析說一說MySQL中的排序問題,希望可以對(duì)正在閱讀的同學(xué)們有所啟迪幫助
    2021-11-11
  • 尋找sql注入的網(wǎng)站的方法(必看)

    尋找sql注入的網(wǎng)站的方法(必看)

    下面小編就為大家?guī)硪黄獙ふ襰ql注入的網(wǎng)站的方法(必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 經(jīng)典mysql連接查詢例題

    經(jīng)典mysql連接查詢例題

    本文通過一個(gè)有趣的例子向我們介紹了mysql連接查詢,采用了子查詢和連接查詢混合和多次連接查詢,需要的朋友可以參考下
    2015-07-07
  • java連接mysql底層封裝詳解

    java連接mysql底層封裝詳解

    這篇文章主要介紹了java連接mysql底層封裝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • MySQL數(shù)據(jù)同步Elasticsearch的4種方案

    MySQL數(shù)據(jù)同步Elasticsearch的4種方案

    本文主要介紹了MySQL數(shù)據(jù)同步Elasticsearch的4種方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 關(guān)于MySQL中Update使用方法舉例

    關(guān)于MySQL中Update使用方法舉例

    這篇文章主要給大家介紹了關(guān)于MySQL中Update使用方法的相關(guān)資料,更新數(shù)據(jù)是使用數(shù)據(jù)庫時(shí)最重要的任務(wù)之一,在本教程中您將學(xué)習(xí)如何使用MySQL UPDATE語句來更新表中的數(shù)據(jù),需要的朋友可以參考下
    2023-11-11
  • select?into?from和insert?into?select的使用舉例詳解

    select?into?from和insert?into?select的使用舉例詳解

    select into from和insert into select都是用來復(fù)制表,下面這篇文章主要給大家介紹了關(guān)于select?into?from和insert?into?select使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • 在Linux系統(tǒng)安裝MySql步驟截圖詳解

    在Linux系統(tǒng)安裝MySql步驟截圖詳解

    本文給大家介紹的是linux系統(tǒng)下使用官方編譯好的二進(jìn)制文件進(jìn)行安裝MySql的安裝過程和安裝截屏,這種安裝方式速度快,安裝步驟簡單。需要的朋友可以參考下在Linux系統(tǒng)安裝MySql步驟截圖詳解
    2016-10-10
  • SQL實(shí)現(xiàn)LeetCode(183.從未下單訂購的顧客)

    SQL實(shí)現(xiàn)LeetCode(183.從未下單訂購的顧客)

    這篇文章主要介紹了SQL實(shí)現(xiàn)LeetCode(182.從未下單訂購的顧客),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

兴义市| 麟游县| 信宜市| 长宁县| 长春市| 儋州市| 曲水县| 南郑县| 遂平县| 宜城市| 柳州市| 和静县| 东辽县| 阜新| 灌南县| 佛教| 名山县| 庐江县| 健康| 武乡县| 磐安县| 迭部县| 龙州县| 镇原县| 武冈市| 久治县| 利辛县| 永顺县| 五指山市| 苏尼特左旗| 荣昌县| 白玉县| 吴堡县| 陇南市| 肃宁县| 宣化县| 阿勒泰市| 南阳市| 合山市| 沽源县| 绵竹市|