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

一文詳解MySQL的并發(fā)控制

 更新時(shí)間:2023年05月27日 10:56:24   作者:_BugMan  
無(wú)論何時(shí)只要有多個(gè)查詢需要在同一時(shí)刻修改數(shù)據(jù),都會(huì)產(chǎn)生并發(fā)控制問(wèn)題,MySQL可以在兩個(gè)層面進(jìn)行并發(fā)控制,服務(wù)器層和存儲(chǔ)引擎層,下面這篇文章主要給大家介紹了關(guān)于MySQL并發(fā)控制的相關(guān)資料,需要的朋友可以參考下

1.概述

所謂的并發(fā)控制,就是規(guī)避多個(gè)會(huì)話并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)帶來(lái)的諸如臟數(shù)據(jù)之類的數(shù)據(jù)一致性問(wèn)題,MySQL中提供了一系列的機(jī)制讓我們可以去進(jìn)行并發(fā)控制。

本質(zhì)上來(lái)說(shuō)MySQL就是用的兩種鎖來(lái)進(jìn)行并發(fā)控制,一種是表鎖,鎖住整張表;一種是行鎖,鎖住某個(gè)數(shù)據(jù)行。

平時(shí)我們使用的時(shí)候,很少會(huì)直接去操作鎖,因?yàn)镸ySQL已經(jīng)幫我們封裝的很好了,直接用innodb引擎+事務(wù)就能很好的進(jìn)行并發(fā)控制,事務(wù)底層其實(shí)依賴的就是行鎖。

本文會(huì)先聊事務(wù)、再聊表鎖、行鎖,但其實(shí)總的來(lái)說(shuō)MySQL進(jìn)行并發(fā)控制,就是行鎖和表鎖,事務(wù)的底層用的就是行鎖,只是事務(wù)太重要了所以單獨(dú)拎出來(lái)作為一個(gè)獨(dú)立的章節(jié)聊。

2.事務(wù)

2.1.什么是事務(wù)

注意:只有innodb引擎是支持事務(wù)的,所以本文與事務(wù)相關(guān)的討論,默認(rèn)都是在innodb引擎下。

在實(shí)際使用中,會(huì)存在這樣一類場(chǎng)景,我們希望幾條SQL要么同時(shí)執(zhí)行成功,要么同時(shí)失敗,不能有的成功,有的失敗。

比如網(wǎng)購(gòu)下單,生成訂單、扣減庫(kù)存兩條SQL,必須保證要么全部成功,要么全部失敗,不能說(shuō)生成訂單成功,但是扣減庫(kù)存失敗了,或者說(shuō)扣減庫(kù)存成功但是生成訂單失敗了,以上任何一種情況都是會(huì)產(chǎn)生臟數(shù)據(jù)的。如果兩者中有一者失敗,另外一個(gè)也需要跟著執(zhí)行不成功,從而保證數(shù)據(jù)的正確性。

事務(wù)就是為了滿足將多條捆綁在一起,同成功,同失敗而出現(xiàn)的。人們?cè)趯?shí)現(xiàn)事務(wù)過(guò)程中,發(fā)現(xiàn)事務(wù)要實(shí)現(xiàn)上面我們說(shuō)的效果,那么就必須實(shí)現(xiàn)四點(diǎn):

  • 原子性(Atomicity)
  • 一致性(Consistent)
  • 隔離性(Isolation)
  • 持久性(Durable)

也就是大名鼎鼎的ACID,很多地方稱其為事務(wù)的四大特性。

1.原子性:

事務(wù)是一個(gè)原子操作單元,其對(duì)數(shù)據(jù)的修改,要么全部執(zhí)行,要么全部不執(zhí)行。

2.一致性:

數(shù)據(jù)庫(kù)中的數(shù)據(jù)總是從一個(gè)狀態(tài)到另一個(gè)狀態(tài),不能存在中間狀態(tài)。繼續(xù)以網(wǎng)購(gòu)下單為例,一開(kāi)始的數(shù)據(jù)庫(kù)中的數(shù)據(jù)為A狀態(tài),執(zhí)行完事務(wù),扣減庫(kù)存、新增訂單后的數(shù)據(jù)狀態(tài)為B狀態(tài),數(shù)據(jù)庫(kù)只能由A到B,不能出現(xiàn)諸如扣了庫(kù)存,沒(méi)生成訂單,或者生成了訂單,沒(méi)扣庫(kù)存這樣的中間狀態(tài)。

3.隔離性:

一個(gè)事務(wù)在提交之前,其所做的修改對(duì)其它事務(wù)來(lái)說(shuō)是不可見(jiàn)的。不保證隔離性會(huì)產(chǎn)生臟數(shù)據(jù),這個(gè)很好理解,舉個(gè)例子:

A的銀行賬戶有400,有兩個(gè)事務(wù),彼此之間數(shù)據(jù)可見(jiàn),也就是一個(gè)事務(wù)修改數(shù)據(jù),不管提沒(méi)提交其他事務(wù)都看得見(jiàn)。

事務(wù)1,A向B轉(zhuǎn)200:

  • A的賬戶扣減200
  • B的賬戶新增200

事務(wù)2,A向C轉(zhuǎn)200:

  • A的賬戶扣減200
  • C的賬戶新增200

如果在事務(wù)1中的1、2步的時(shí)間間隙內(nèi)事務(wù)2間插執(zhí)行完畢,那么在事務(wù)1第2步執(zhí)行前A的賬戶中已經(jīng)被扣減了兩次200,余額為0,C的賬戶中多了200。

這時(shí)候如果在事務(wù)1的第2步中出錯(cuò)了、回滾,那么A的賬戶又會(huì)回到事務(wù)1第一步執(zhí)行之前的狀態(tài),也就是A的賬戶又恢復(fù)成了400。最后C的賬戶平白無(wú)故多了200。

4.持久性:

事務(wù)完成后,其對(duì)數(shù)據(jù)的修改是永久的,即使系統(tǒng)斷電、重啟,也不會(huì)變。

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

2.2.1.三種數(shù)據(jù)一致性問(wèn)題

在沒(méi)有隔離性的情況下,事物之間會(huì)出現(xiàn)3種數(shù)據(jù)一致性問(wèn)題:

  • 臟讀:事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù),然后B回滾操作,那么A讀取到的數(shù)據(jù)是臟數(shù)據(jù)
  • 不可重復(fù)讀:事務(wù) A 多次讀取同一數(shù)據(jù),事務(wù) B 在事務(wù)A多次讀取的過(guò)程中,對(duì)數(shù)據(jù)作了更新并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí),結(jié)果 不一致。
  • 幻讀:系統(tǒng)管理員A將數(shù)據(jù)庫(kù)中所有學(xué)生的成績(jī)從具體分?jǐn)?shù)改為ABCDE等級(jí),但是系統(tǒng)管理員B就在這個(gè)時(shí)候插入了一條具體分?jǐn)?shù)的記錄,當(dāng)系統(tǒng)管理員A改結(jié)束后發(fā)現(xiàn)還有一條記錄沒(méi)有改過(guò)來(lái),就好像發(fā)生了幻覺(jué)一樣,這就叫幻讀。

2.2.2.四種隔離級(jí)別

隔離級(jí)別可理解為,隔離性的嚴(yán)格度,MySQL并不是固定死了各個(gè)事務(wù)間就是不可讀的,而是規(guī)定了各種強(qiáng)度的隔離級(jí)別。

觀察上面3種數(shù)據(jù)一致性問(wèn)題就會(huì)發(fā)現(xiàn),解決它們需要的隔離性是遞增的,MySQL一共給出4種隔離級(jí)別,隔離性也是遞增的,對(duì)應(yīng)解決以上3個(gè)問(wèn)題,有3種,加上1種3種問(wèn)題都能覆蓋解決的:

  1. Read Uncommitted(讀未提交):最低的隔離級(jí)別,允許一個(gè)事務(wù)讀取另一個(gè)事務(wù)尚未提交的數(shù)據(jù)變更??赡軐?dǎo)致臟讀(Dirty Read)問(wèn)題。
  2. Read Committed(讀已提交):確保一個(gè)事務(wù)只能讀取另一個(gè)事務(wù)已經(jīng)提交的數(shù)據(jù)變更。防止臟讀問(wèn)題,但可能導(dǎo)致不可重復(fù)讀(Non-repeatable Read)問(wèn)題。
  3. Repeatable Read(可重復(fù)讀):確保在同一個(gè)事務(wù)中多次讀取同一數(shù)據(jù)時(shí),能夠得到一致的結(jié)果。防止臟讀和不可重復(fù)讀問(wèn)題,但可能導(dǎo)致幻讀(Phantom Read)問(wèn)題。
  4. Serializable(串行化):最高的隔離級(jí)別,強(qiáng)制事務(wù)串行執(zhí)行,確保不會(huì)發(fā)生臟讀、不可重復(fù)讀和幻讀問(wèn)題。但是并發(fā)性能較差,通常不建議在高并發(fā)環(huán)境中使用。

2.3.如何設(shè)置隔離級(jí)別

可以在連接字符串中設(shè)置隔離級(jí)別:

jdbc:mysql://localhost/mydatabase?useSSL=false&characterEncoding=utf8&transactionIsolation=隔離級(jí)別

可以通過(guò)SQL在會(huì)話中設(shè)置隔離級(jí)別:

SET TRANSACTION ISOLATION LEVEL 隔離級(jí)別;

3.鎖

3.1.鎖與事務(wù)的關(guān)系

鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問(wèn)某一資源的機(jī)制,用來(lái)解決并發(fā)訪問(wèn)帶來(lái)的數(shù)據(jù)一致性問(wèn)題。在數(shù)據(jù)庫(kù)中,除傳統(tǒng)的計(jì)算資源(如CPU、IO、RAM)的爭(zhēng)用以外,數(shù)據(jù)更是會(huì)被并發(fā)訪問(wèn)的資源。所以MySQL數(shù)據(jù)庫(kù)也用鎖機(jī)制來(lái)保證數(shù)據(jù)并發(fā)訪問(wèn)的一致性。

不同的隔離級(jí)別底層就是用不同的鎖來(lái)實(shí)現(xiàn)的。

3.2.分類

MySQL的鎖可以從兩種維度來(lái)分,

一個(gè)維度是按照鎖的是一行,還是鎖的是整張表,分為:

  • 行鎖
  • 表鎖

另一個(gè)維度是按照鎖的操作是讀操作,還是寫(xiě)操作,分為:

  • 讀鎖
  • 寫(xiě)鎖

3.3.表鎖

3.3.1.概述

MySQL中innodb引擎和myisam引擎均支持用lock tables指令來(lái)鎖表。

3.3.2.讀鎖

讀鎖,一種共享鎖,針對(duì)被鎖表,所有會(huì)話都可以進(jìn)行讀操作,所有會(huì)話都無(wú)法進(jìn)行寫(xiě)操作。加鎖方和其他客戶端的區(qū)別是,加鎖方直接不允許進(jìn)行寫(xiě)操作,而其他會(huì)話的寫(xiě)操作允許進(jìn)行,只是會(huì)被阻塞掛起。鎖解開(kāi)后,所有掛起的操作線程會(huì)去重新?tīng)?zhēng)搶資源。

加鎖指令:

lock tables 表名 read;

釋放鎖指令:

unlock tanles;

加鎖方不允許進(jìn)行寫(xiě)操作:

其它客戶端的寫(xiě)操作在加鎖方釋放鎖之前都被掛起:

3.3.3.寫(xiě)鎖

寫(xiě)鎖,排它鎖,針對(duì)被鎖表,加鎖方可以讀寫(xiě),其他會(huì)話的寫(xiě)操作會(huì)直接失敗,讀操作會(huì)被阻塞掛起,解鎖以后,被掛起的線程會(huì)重新去爭(zhēng)搶資源。

加鎖指令:

lock tables 表名 write;

其它會(huì)話的讀操作、寫(xiě)操作在加鎖方釋放鎖之前都被阻塞掛起:

 

3.3.4.保護(hù)機(jī)制

讀鎖、寫(xiě)鎖中,加鎖方都只能讀當(dāng)前被自己鎖定的表,這是MySQL的一個(gè)保護(hù)機(jī)制,為的就是強(qiáng)制要求加鎖方給出一個(gè)說(shuō)法,到底準(zhǔn)備鎖多久,不給說(shuō)法不讓走。

3.4.行鎖

3.4.1.概述

innodb和myIsam最大的不同有兩點(diǎn),一是支持事務(wù),二是支持行級(jí)鎖。

3.4.2.什么是MVCC

行鎖沒(méi)有顯式的聲明辦法,而是藏在默認(rèn)實(shí)現(xiàn)中,MVCC 是 MySQL InnoDB 存儲(chǔ)引擎的默認(rèn)并發(fā)控制機(jī)制,其采用的就是表鎖。

并發(fā)控制有幾種處理方法,

第一種: 基于鎖的并發(fā)控制,程序員B開(kāi)始修改數(shù)據(jù)時(shí),給這些數(shù)據(jù)加上鎖,程序員A這時(shí)再讀,就發(fā)現(xiàn)讀取不了,處于等待情況,只能等B操作完才能讀數(shù)據(jù),這保證A不會(huì)讀到一個(gè)不一致的數(shù)據(jù),但是這個(gè)會(huì)影響程序的運(yùn)行效率。

第二種:MVCC,每個(gè)用戶連接數(shù)據(jù)庫(kù)時(shí),看到的都是某一特定時(shí)刻的數(shù)據(jù)庫(kù)快照,在B的事務(wù)沒(méi)有提交之前,A始終讀到的是某一特定時(shí)刻的數(shù)據(jù)庫(kù)快照,不會(huì)讀到B事務(wù)中的數(shù)據(jù)修改情況,直到B事務(wù)提交,才會(huì)讀取B的修改內(nèi)容。

MVCC其實(shí)就是實(shí)現(xiàn)事務(wù)的關(guān)鍵,后續(xù)會(huì)有文章專門(mén)深入聊事務(wù)的實(shí)現(xiàn),此處暫不展開(kāi)。

3.4.3.mvcc的使用

首先有一個(gè)需要糾正的是,很多地方都說(shuō)mvcc是通過(guò)手動(dòng)提交來(lái)觸發(fā)的,這是個(gè)誤導(dǎo),不管手動(dòng)提交還是自動(dòng)提交MVCC機(jī)制都是生效的,只是手動(dòng)提交用來(lái)觀察mvcc過(guò)程更加直觀。

此處為了直觀,我們也以手動(dòng)提交為例,首先通過(guò)set  autocommit=0可以關(guān)閉自動(dòng)提交。關(guān)閉后每次執(zhí)行sql以后,通過(guò)commit命令來(lái)手動(dòng)提交,才會(huì)對(duì)數(shù)據(jù)庫(kù)產(chǎn)生影響,否則只會(huì)對(duì)當(dāng)前操作方的數(shù)據(jù)快照有影響。innodb引擎中,其他客戶端想查看到最新的數(shù)據(jù)情況也必須通過(guò)commit指令來(lái)做一次同步(因?yàn)閕nnodb默認(rèn)隔離級(jí)別為可重復(fù)讀)。

當(dāng)一個(gè)會(huì)話修改某行數(shù)據(jù),未commit前,其他會(huì)話對(duì)該行數(shù)據(jù)的修改會(huì)阻塞掛起,直到先改那個(gè)會(huì)話commit為止。

3.4.4.間隙鎖

使用范圍條件匹配時(shí),innodb會(huì)給符合條件的已有數(shù)據(jù)記錄的索引加“范圍鎖”(范圍鎖是特殊的行鎖),對(duì)于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做間隙(GAP),innodb也會(huì)對(duì)這個(gè)間隙加鎖,這種機(jī)制叫做“間隙鎖”。

3.4.5.行鎖變表鎖 

任何需要全表掃描的情況時(shí),行鎖都會(huì)升級(jí)為表鎖。

因?yàn)镸ySQL不知道到底該鎖哪行,所以會(huì)將整個(gè)表都鎖起來(lái),然后再進(jìn)行全表掃描。

全表掃描的情況無(wú)非兩種:

  • 沒(méi)建索引。
  • 索引失效。

總結(jié)

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

相關(guān)文章

  • MySQL如何新建用戶并授權(quán)

    MySQL如何新建用戶并授權(quán)

    本文主要介紹了如何在MySQL中創(chuàng)建新用戶并管理其權(quán)限,包括增刪改查、創(chuàng)建表、刪除表等操作,文中詳細(xì)說(shuō)明了MySQL 5.7.18和MySQL 8.0版本中的權(quán)限配置,以及如何根據(jù)需要添加或刪除權(quán)限的步驟,旨在提供實(shí)用的數(shù)據(jù)庫(kù)管理技巧
    2024-10-10
  • MySQL8.0臨時(shí)表空間的使用及解讀

    MySQL8.0臨時(shí)表空間的使用及解讀

    MySQL 8.0+引入會(huì)話級(jí)(temp_N.ibt)和全局(ibtmp1)InnoDB臨時(shí)表空間,用于存儲(chǔ)臨時(shí)數(shù)據(jù)及事務(wù)日志,自動(dòng)創(chuàng)建與回收,重啟釋放,管理高效
    2025-09-09
  • MySQL實(shí)現(xiàn)索引下推的示例代碼

    MySQL實(shí)現(xiàn)索引下推的示例代碼

    索引下推是一種數(shù)據(jù)庫(kù)查詢優(yōu)化技術(shù),通過(guò)在索引掃描階段應(yīng)用過(guò)濾條件,減少回表操作,本文主要介紹了MySQL實(shí)現(xiàn)索引下推的示例代碼,感興趣的可以了解一下
    2025-02-02
  • 教你如何恢復(fù)使用MEB備份的MySQL數(shù)據(jù)庫(kù)

    教你如何恢復(fù)使用MEB備份的MySQL數(shù)據(jù)庫(kù)

    這篇文章主要介紹了教你如何恢復(fù)使用MEB備份的MySQL數(shù)據(jù)庫(kù)的具體方法,需要的朋友可以參考下
    2016-09-09
  • Mysql5.5升級(jí)到5.6的真實(shí)操作步驟示例

    Mysql5.5升級(jí)到5.6的真實(shí)操作步驟示例

    MySQL5.5升級(jí)到5.6涉及下載升級(jí)包、數(shù)據(jù)權(quán)限備份、配置文件備份、解壓安裝、數(shù)據(jù)導(dǎo)入、重啟服務(wù)、配置恢復(fù)等步驟
    2024-11-11
  • MYSQL中的json數(shù)據(jù)操作代碼

    MYSQL中的json數(shù)據(jù)操作代碼

    這篇文章主要介紹了MYSQL中的json數(shù)據(jù)操作,主要包括基礎(chǔ)查詢操作,JSON函數(shù)操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • mysql隨機(jī)查詢?nèi)舾蓷l數(shù)據(jù)的方法

    mysql隨機(jī)查詢?nèi)舾蓷l數(shù)據(jù)的方法

    這篇文章主要介紹了mysql中獲取隨機(jī)內(nèi)容的方法,需要的朋友可以參考下
    2013-10-10
  • MySql 存儲(chǔ)引擎和索引相關(guān)知識(shí)總結(jié)

    MySql 存儲(chǔ)引擎和索引相關(guān)知識(shí)總結(jié)

    這篇文章主要介紹了MySql 存儲(chǔ)引擎和索引相關(guān)知識(shí)總結(jié),文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • union和子查詢中order?by一起使用導(dǎo)致排序失效問(wèn)題及解決

    union和子查詢中order?by一起使用導(dǎo)致排序失效問(wèn)題及解決

    這篇文章主要介紹了union和子查詢中order?by一起使用導(dǎo)致排序失效問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • MySQL中常用查看鎖和事務(wù)的SQL語(yǔ)句詳解

    MySQL中常用查看鎖和事務(wù)的SQL語(yǔ)句詳解

    這篇文章主要介紹了MySQL中常用查看鎖和事務(wù)的SQL語(yǔ)句,用于查看鎖和事務(wù)的狀態(tài),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07

最新評(píng)論

广河县| 夏邑县| 理塘县| 彰化县| 梁平县| 文昌市| 日照市| 垣曲县| 利辛县| 平南县| 墨竹工卡县| 抚宁县| 东台市| 普陀区| 邵东县| 雷波县| 汶川县| 龙州县| 宜城市| 重庆市| 崇信县| 平乐县| 海宁市| 长汀县| 辽宁省| 芷江| 凌源市| 蒙阴县| 赤城县| 岚皋县| 淮南市| 开江县| 杭锦后旗| 金乡县| 正蓝旗| 吴旗县| 卢龙县| 黄冈市| 大兴区| 建瓯市| 浦北县|