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

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

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

1.概述

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

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

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

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

2.事務(wù)

2.1.什么是事務(wù)

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

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

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

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

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

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

1.原子性:

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

2.一致性:

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

3.隔離性:

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

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

事務(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的賬戶又會回到事務(wù)1第一步執(zhí)行之前的狀態(tài),也就是A的賬戶又恢復(fù)成了400。最后C的賬戶平白無故多了200。

4.持久性:

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

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

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

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

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

2.2.2.四種隔離級別

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

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

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

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

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

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

可以通過SQL在會話中設(shè)置隔離級別:

SET TRANSACTION ISOLATION LEVEL 隔離級別;

3.鎖

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

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

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

3.2.分類

MySQL的鎖可以從兩種維度來分,

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

  • 行鎖
  • 表鎖

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

  • 讀鎖
  • 寫鎖

3.3.表鎖

3.3.1.概述

MySQL中innodb引擎和myisam引擎均支持用lock tables指令來鎖表。

3.3.2.讀鎖

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

加鎖指令:

lock tables 表名 read;

釋放鎖指令:

unlock tanles;

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

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

3.3.3.寫鎖

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

加鎖指令:

lock tables 表名 write;

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

 

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

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

3.4.行鎖

3.4.1.概述

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

3.4.2.什么是MVCC

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

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

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

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

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

3.4.3.mvcc的使用

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

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

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

3.4.4.間隙鎖

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

3.4.5.行鎖變表鎖 

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

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

全表掃描的情況無非兩種:

  • 沒建索引。
  • 索引失效。

總結(jié)

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

相關(guān)文章

  • MySQL?優(yōu)化?index?merge引起的死鎖分析

    MySQL?優(yōu)化?index?merge引起的死鎖分析

    這篇文章主要介紹了MySQL?優(yōu)化?index?merge引起的死鎖分析,MySQL通過優(yōu)化索引合并是遇到的死鎖問題,下面具體分析需要的小伙伴可以參考一下
    2022-04-04
  • Mysql多表關(guān)聯(lián)不走索引的原因及分析

    Mysql多表關(guān)聯(lián)不走索引的原因及分析

    這篇文章主要介紹了Mysql多表關(guān)聯(lián)不走索引的原因及分析,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • mysql數(shù)據(jù)庫操作_高手進(jìn)階常用的sql命令語句大全

    mysql數(shù)據(jù)庫操作_高手進(jìn)階常用的sql命令語句大全

    mysql數(shù)據(jù)庫操作sql命令語句大全:三表連表查詢、更新時(shí)批量替換字段部分字符、判斷某一張表是否存在、自動(dòng)增長恢復(fù)從1開始、查詢重復(fù)記錄、更新時(shí)字段值等于原值加上一個(gè)字符串、更新某字段為隨機(jī)值、復(fù)制表數(shù)據(jù)到另一個(gè)表、創(chuàng)建表時(shí)拷貝其他表的數(shù)據(jù)和結(jié)構(gòu)...
    2022-11-11
  • MySQL中with?rollup的用法及說明

    MySQL中with?rollup的用法及說明

    這篇文章主要介紹了MySQL中with?rollup的用法及說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 在 Windows 10 上安裝 解壓縮版 MySql(推薦)

    在 Windows 10 上安裝 解壓縮版 MySql(推薦)

    這篇文章主要介紹了在 Windows 10 上安裝 解壓縮版 MySql(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-12-12
  • Mysql 5.6使用配置文件my.ini來設(shè)置長時(shí)間連接數(shù)據(jù)庫的問題

    Mysql 5.6使用配置文件my.ini來設(shè)置長時(shí)間連接數(shù)據(jù)庫的問題

    這篇文章主要介紹了Mysql 5.6使用配置文件my.ini來設(shè)置長時(shí)間連接數(shù)據(jù)庫,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • MySQL pt-slave-restart工具的使用簡介

    MySQL pt-slave-restart工具的使用簡介

    這篇文章主要介紹了MySQL pt-slave-restart工具的使用簡介,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-04-04
  • CentOS 7下MySQL服務(wù)啟動(dòng)失敗的快速解決方法

    CentOS 7下MySQL服務(wù)啟動(dòng)失敗的快速解決方法

    CentOS 7下MySQL服務(wù)啟動(dòng)失敗怎么辦?下面小編就為大家?guī)硪黄狢entOS 7下MySQL服務(wù)啟動(dòng)失敗的快速解決方法?,F(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-03-03
  • 將數(shù)據(jù)插入到MySQL表中的詳細(xì)教程

    將數(shù)據(jù)插入到MySQL表中的詳細(xì)教程

    這篇文章主要介紹了將數(shù)據(jù)插入到MySQL表中的詳細(xì)教程,文中給出了在PHP腳本中操作的示例,是MySQL入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-05-05
  • MySQL數(shù)據(jù)庫中varchar類型的數(shù)字比較大小的方法

    MySQL數(shù)據(jù)庫中varchar類型的數(shù)字比較大小的方法

    varchar類型的數(shù)據(jù)是不能直接比較大小的,那么MySQL數(shù)據(jù)庫中varchar類型如何進(jìn)行數(shù)字比較大小的,本文就詳細(xì)的介紹一下
    2021-11-11

最新評論