• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

    MySql的隔離級(jí)別和鎖的關(guān)系_MySQL

    來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-09 20:18:24
    文檔

    MySql的隔離級(jí)別和鎖的關(guān)系_MySQL

    MySql的隔離級(jí)別和鎖的關(guān)系_MySQL:一、事務(wù)的4個(gè)基本特征 Atomic(原子性): 事務(wù)中包含的操作被看做一個(gè)邏輯單元,這個(gè)邏輯單元中的操作要 么全部成功,要么全部失敗。 Consistency(一致性): 只有合法的數(shù)據(jù)可以被寫入數(shù)據(jù)庫(kù),否則事務(wù)應(yīng)該將其回滾到最初 狀態(tài)。 Isolation
    推薦度:
    導(dǎo)讀MySql的隔離級(jí)別和鎖的關(guān)系_MySQL:一、事務(wù)的4個(gè)基本特征 Atomic(原子性): 事務(wù)中包含的操作被看做一個(gè)邏輯單元,這個(gè)邏輯單元中的操作要 么全部成功,要么全部失敗。 Consistency(一致性): 只有合法的數(shù)據(jù)可以被寫入數(shù)據(jù)庫(kù),否則事務(wù)應(yīng)該將其回滾到最初 狀態(tài)。 Isolation
    一、事務(wù)的4個(gè)基本特征

    Atomic(原子性):
    事務(wù)中包含的操作被看做一個(gè)邏輯單元,這個(gè)邏輯單元中的操作要
    么全部成功,要么全部失敗。

    Consistency(一致性):
    只有合法的數(shù)據(jù)可以被寫入數(shù)據(jù)庫(kù),否則事務(wù)應(yīng)該將其回滾到最初
    狀態(tài)。

    Isolation(隔離性):
    事務(wù)允許多個(gè)用戶對(duì)同一個(gè)數(shù)據(jù)進(jìn)行并發(fā)訪問,而不破壞數(shù)據(jù)的正
    確性和完整性。同時(shí),并行事務(wù)的修改必須與其他并行事務(wù)的修改
    相互獨(dú)立。

    Durability(持久性):
    事務(wù)結(jié)束后,事務(wù)處理的結(jié)果必須能夠得到固化。

    二、數(shù)據(jù)庫(kù)隔離級(jí)別

    數(shù)據(jù)庫(kù)事務(wù)的隔離級(jí)別有4個(gè),由低到高依次為Read uncommitted、Read committed、Repeatable read、Serializable,這四個(gè)級(jí)別可以逐個(gè)解決臟讀、不可重復(fù)讀、幻讀這幾類問題。MySql設(shè)置的隔離級(jí)別默認(rèn)為Repeatable Read,可重復(fù)讀級(jí)別。隔離級(jí)別可以配置。

    √: 可能出現(xiàn)×: 不會(huì)出現(xiàn)

    臟讀 不可重復(fù)讀 幻讀
    Read uncommitted
    Read committed ×
    Repeatable read × ×
    Serializable × × ×

    注意:我們討論隔離級(jí)別的場(chǎng)景,主要是在多個(gè)事務(wù)并發(fā)的情況下,因此,接下來(lái)的講解都圍繞事務(wù)并發(fā)。

    Read uncommitted 讀未提交

    READ UNCOMMITTED是限制性最弱的隔離級(jí)別,因?yàn)樵摷?jí)別忽略其他事務(wù)放置的鎖。使用READ UNCOMMITTED級(jí)別執(zhí)行的事務(wù),可以讀取尚未由其他事務(wù)提交的修改后的數(shù)據(jù)值,這些行為稱為“臟”讀。我們所說的臟讀,兩個(gè)并發(fā)的事務(wù),“事務(wù)A:領(lǐng)導(dǎo)給singo發(fā)工資”、“事務(wù)B:singo查詢工資賬戶”,事務(wù)B讀取了事務(wù)A尚未提交的數(shù)據(jù)。比如,事務(wù)1修改一行,事務(wù)2在事務(wù)1提交之前讀取了這一行。如果事務(wù)1回滾,事務(wù)2就讀取了一行沒有提交的數(shù)據(jù),這樣的數(shù)據(jù)我們認(rèn)為是不存在的。

    Read committed 讀提交
    該級(jí)別通過指定語(yǔ)句不能讀取其他事務(wù)已修改但是尚未提交的數(shù)據(jù)值,禁止執(zhí)行臟讀。在當(dāng)前事務(wù)中的各個(gè)語(yǔ)句執(zhí)行之間,其他事務(wù)仍可以修改、插入或刪除數(shù)據(jù),從而產(chǎn)生無(wú)法重復(fù)的讀操作,或“影子”數(shù)據(jù)。比如,事務(wù)1讀取了一行,事務(wù)2修改或者刪除這一行并且提交。如果事務(wù)1想再一次讀取這一行,它將獲得修改后的數(shù)據(jù)或者發(fā)現(xiàn)這一樣已經(jīng)被刪除,因此事務(wù)的第二次讀取結(jié)果與第一次讀取結(jié)果不同,因此也叫不可重復(fù)讀。

    大多數(shù)數(shù)據(jù)庫(kù)的默認(rèn)級(jí)別就是Read committed,比如Sql Server , Oracle。如何解決不可重復(fù)讀這一問題,請(qǐng)看下一個(gè)隔離級(jí)別。

    Repeatable read 重復(fù)讀
    REPEATABLE READ是比READ COMMITTED限制性更強(qiáng)的隔離級(jí)別。該級(jí)別包括READ COMMITTED,并且另外指定了在當(dāng)前事務(wù)提交之前,其他任何事務(wù)均不可以修改或刪除當(dāng)前事務(wù)已讀取的數(shù)據(jù)。并發(fā)性低于READ COMMITTED,因?yàn)橐炎x數(shù)據(jù)的共享鎖在整個(gè)事務(wù)期間持有,而不是在每個(gè)語(yǔ)句結(jié)束時(shí)釋放。這個(gè)隔離級(jí)別只是說,不能夠修改和刪除,但是并沒有強(qiáng)制不能插入新的滿足條件查詢的數(shù)據(jù)行。此可以得出結(jié)論:REPEATABLE READ隔離級(jí)別保證了在相同的查詢條件下,同一個(gè)事務(wù)中的兩個(gè)查詢,第二次讀取的內(nèi)容肯定包換第一次讀到的內(nèi)容。注:Mysql的默認(rèn)隔離級(jí)別就是Repeatable read。

    重復(fù)讀與幻讀

    重復(fù)讀是為了保證在一個(gè)事務(wù)中,相同查詢條件下讀取的數(shù)據(jù)值不發(fā)生改變,但是不能保證下次同樣條件查詢,結(jié)果記錄數(shù)不會(huì)增加。

    幻讀就是為了解決這個(gè)問題而存在的,他將這個(gè)查詢范圍都加鎖了,所以就不能再往這個(gè)范圍內(nèi)插入數(shù)據(jù),這就是SERIALIZABLE 隔離級(jí)別做的事情。

    Serializable 序列化
    SERIALIZABLE是限制性最強(qiáng)的隔離級(jí)別,因?yàn)樵摷?jí)別鎖定整個(gè)范圍的鍵,并一直持有鎖,直到事務(wù)完成。該級(jí)別包括REPEATABLE READ,并增加了在事務(wù)完成之前,其他事務(wù)不能向事務(wù)已讀取的范圍插入新行的限制。比如,事務(wù)1讀取了一系列滿足搜索條件的行。事務(wù)2在執(zhí)行SQL statement產(chǎn)生一行或者多行滿足事務(wù)1搜索條件的行時(shí)會(huì)沖突,則事務(wù)2回滾。這時(shí)事務(wù)1再次讀取了一系列滿足相同搜索條件的行,第二次讀取的結(jié)果和第一次讀取的結(jié)果相同。

    三、鎖

    一次封鎖or兩段鎖?
    因?yàn)橛写罅康牟l(fā)訪問,為了預(yù)防死鎖,一般應(yīng)用中推薦使用一次封鎖法,就是在方法的開始階段,已經(jīng)預(yù)先知道會(huì)用到哪些數(shù)據(jù),然后全部鎖住,在方法運(yùn)行之后,再全部解鎖。這種方式可以有效的避免循環(huán)死鎖,但在數(shù)據(jù)庫(kù)中卻不適用,因?yàn)樵谑聞?wù)開始階段,數(shù)據(jù)庫(kù)并不知道會(huì)用到哪些數(shù)據(jù)。
    數(shù)據(jù)庫(kù)遵循的是兩段鎖協(xié)議,將事務(wù)分成兩個(gè)階段,加鎖階段和解鎖階段(所以叫兩段鎖)

    加鎖階段:在該階段可以進(jìn)行加鎖操作。在對(duì)任何數(shù)據(jù)進(jìn)行讀操作之前要申請(qǐng)并獲得S鎖(共享鎖,其它事務(wù)可以繼續(xù)加共享鎖,但不能加排它鎖),在進(jìn)行寫操作之前要申請(qǐng)并獲得X鎖(排它鎖,其它事務(wù)不能再獲得任何鎖)。加鎖不成功,則事務(wù)進(jìn)入等待狀態(tài),直到加鎖成功才繼續(xù)執(zhí)行。
    解鎖階段:當(dāng)事務(wù)釋放了一個(gè)封鎖以后,事務(wù)進(jìn)入解鎖階段,在該階段只能進(jìn)行解鎖操作不能再進(jìn)行加鎖操作。
    事務(wù) 加鎖/解鎖處理
    begin;
    insert into test .....加insert對(duì)應(yīng)的鎖
    update test set...加update對(duì)應(yīng)的鎖
    delete from test ....加delete對(duì)應(yīng)的鎖
    commit;事務(wù)提交時(shí),同時(shí)釋放insert、update、delete對(duì)應(yīng)的鎖
    這種方式雖然無(wú)法避免死鎖,但是兩段鎖協(xié)議可以保證事務(wù)的并發(fā)調(diào)度是串行化(串行化很重要,尤其是在數(shù)據(jù)恢復(fù)和備份的時(shí)候)的。

    不可重復(fù)讀和幻讀的區(qū)別
    很多人容易搞混不可重復(fù)讀和幻讀,確實(shí)這兩者有些相似。但不可重復(fù)讀重點(diǎn)在于update和delete,而幻讀的重點(diǎn)在于insert。

    如果使用鎖機(jī)制來(lái)實(shí)現(xiàn)這兩種隔離級(jí)別,在可重復(fù)讀中,該sql第一次讀取到數(shù)據(jù)后,就將這些數(shù)據(jù)加鎖,其它事務(wù)無(wú)法修改這些數(shù)據(jù),就可以實(shí)現(xiàn)可重復(fù)讀了。但這種方法卻無(wú)法鎖住insert的數(shù)據(jù),所以當(dāng)事務(wù)A先前讀取了數(shù)據(jù),或者修改了全部數(shù)據(jù),事務(wù)B還是可以insert數(shù)據(jù)提交,這時(shí)事務(wù)A就會(huì)發(fā)現(xiàn)莫名其妙多了一條之前沒有的數(shù)據(jù),這就是幻讀,不能通過行鎖來(lái)避免。需要Serializable隔離級(jí)別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這么做可以有效的避免幻讀、不可重復(fù)讀、臟讀等問題,但會(huì)極大的降低數(shù)據(jù)庫(kù)的并發(fā)能力。

    所以說不可重復(fù)讀和幻讀最大的區(qū)別,就在于如何通過鎖機(jī)制來(lái)解決他們產(chǎn)生的問題。

    上文說的,是使用悲觀鎖機(jī)制來(lái)處理這兩種問題,但是MySQL、ORACLE、PostgreSQL等成熟的數(shù)據(jù)庫(kù),出于性能考慮,都是使用了以樂觀鎖為理論基礎(chǔ)的MVCC(多版本并發(fā)控制)來(lái)避免這兩種問題。

    悲觀鎖和樂觀鎖
    悲觀鎖
    正如其名,它指的是對(duì)數(shù)據(jù)被外界(包括本系統(tǒng)當(dāng)前的其他事務(wù),以及來(lái)自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度,因此,在整個(gè)數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實(shí)現(xiàn),往往依靠數(shù)據(jù)庫(kù)提供的鎖機(jī)制(也只有數(shù)據(jù)庫(kù)層提供的鎖機(jī)制才能真正保證數(shù)據(jù)訪問的排他性,否則,即使在本系統(tǒng)中實(shí)現(xiàn)了加鎖機(jī)制,也無(wú)法保證外部系統(tǒng)不會(huì)修改數(shù)據(jù))。

    在悲觀鎖的情況下,為了保證事務(wù)的隔離性,就需要一致性鎖定讀。讀取數(shù)據(jù)時(shí)給加鎖,其它事務(wù)無(wú)法修改這些數(shù)據(jù)。修改刪除數(shù)據(jù)時(shí)也要加鎖,其它事務(wù)無(wú)法讀取這些數(shù)據(jù)。

    樂觀鎖
    相對(duì)悲觀鎖而言,樂觀鎖機(jī)制采取了更加寬松的加鎖機(jī)制。悲觀鎖大多數(shù)情況下依靠數(shù)據(jù)庫(kù)的鎖機(jī)制實(shí)現(xiàn),以保證操作最大程度的獨(dú)占性。但隨之而來(lái)的就是數(shù)據(jù)庫(kù)性能的大量開銷,特別是對(duì)長(zhǎng)事務(wù)而言,這樣的開銷往往無(wú)法承受。

    而樂觀鎖機(jī)制在一定程度上解決了這個(gè)問題。樂觀鎖,大多是基于數(shù)據(jù)版本( Version )記錄機(jī)制實(shí)現(xiàn)。何謂數(shù)據(jù)版本?即為數(shù)據(jù)增加一個(gè)版本標(biāo)識(shí),在基于數(shù)據(jù)庫(kù)表的版本解決方案中,一般是通過為數(shù)據(jù)庫(kù)表增加一個(gè) “version” 字段來(lái)實(shí)現(xiàn)。讀取出數(shù)據(jù)時(shí),將此版本號(hào)一同讀出,之后更新時(shí),對(duì)此版本號(hào)加一。此時(shí),將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫(kù)表對(duì)應(yīng)記錄的當(dāng)前版本信息進(jìn)行比對(duì),如果提交的數(shù)據(jù)版本號(hào)大于數(shù)據(jù)庫(kù)表當(dāng)前版本號(hào),則予以更新,否則認(rèn)為是過期數(shù)據(jù)。

    要說明的是,MVCC的實(shí)現(xiàn)沒有固定的規(guī)范,每個(gè)數(shù)據(jù)庫(kù)都會(huì)有不同的實(shí)現(xiàn)方式,這里討論的是InnoDB的MVCC。

    MVCC在MySQL的InnoDB中的實(shí)現(xiàn)
    在InnoDB中,會(huì)在每行數(shù)據(jù)后添加兩個(gè)額外的隱藏的值來(lái)實(shí)現(xiàn)MVCC,這兩個(gè)值一個(gè)記錄這行數(shù)據(jù)何時(shí)被創(chuàng)建,另外一個(gè)記錄這行數(shù)據(jù)何時(shí)過期(或者被刪除)。 在實(shí)際操作中,存儲(chǔ)的并不是時(shí)間,而是事務(wù)的版本號(hào),每開啟一個(gè)新事務(wù),事務(wù)的版本號(hào)就會(huì)遞增。 在可重讀Repeatable reads事務(wù)隔離級(jí)別下:

    SELECT時(shí),讀取創(chuàng)建版本號(hào)<=當(dāng)前事務(wù)版本號(hào),刪除版本號(hào)為空或>當(dāng)前事務(wù)版本號(hào)。

    INSERT時(shí),保存當(dāng)前事務(wù)版本號(hào)為行的創(chuàng)建版本號(hào)

    DELETE時(shí),保存當(dāng)前事務(wù)版本號(hào)為行的刪除版本號(hào)

    UPDATE時(shí),插入一條新紀(jì)錄,保存當(dāng)前事務(wù)版本號(hào)為行創(chuàng)建版本號(hào),同時(shí)保存當(dāng)前事務(wù)版本號(hào)到原來(lái)刪除的行

    通過MVCC,雖然每行記錄都需要額外的存儲(chǔ)空間,更多的行檢查工作以及一些額外的維護(hù)工作,但可以減少鎖的使用,大多數(shù)讀操作都不用加鎖,讀數(shù)據(jù)操作很簡(jiǎn)單,性能很好,并且也能保證只會(huì)讀取到符合標(biāo)準(zhǔn)的行,也只鎖住必要行。

    我們不管從數(shù)據(jù)庫(kù)方面的教課書中學(xué)到,還是從網(wǎng)絡(luò)上看到,大都是上文中事務(wù)的四種隔離級(jí)別這一模塊列出的意思,RR級(jí)別是可重復(fù)讀的,但無(wú)法解決幻讀,而只有在Serializable級(jí)別才能解決幻讀。于是我就加了一個(gè)事務(wù)C來(lái)展示效果。在事務(wù)C中添加了一條teacher_id=1的數(shù)據(jù)commit,RR級(jí)別中應(yīng)該會(huì)有幻讀現(xiàn)象,事務(wù)A在查詢teacher_id=1的數(shù)據(jù)時(shí)會(huì)讀到事務(wù)C新加的數(shù)據(jù)。但是測(cè)試后發(fā)現(xiàn),在MySQL中是不存在這種情況的,在事務(wù)C提交后,事務(wù)A還是不會(huì)讀到這條數(shù)據(jù)。可見在MySQL的RR級(jí)別中,是解決了幻讀的讀問題的。參見下圖

    20151125164322895.png (1530×1093)


    Serializable
    這個(gè)級(jí)別很簡(jiǎn)單,讀加共享鎖,寫加排他鎖,讀寫互斥。使用的悲觀鎖的理論,實(shí)現(xiàn)簡(jiǎn)單,數(shù)據(jù)更加安全,但是并發(fā)能力非常差。如果你的業(yè)務(wù)并發(fā)的特別少或者沒有并發(fā),同時(shí)又要求數(shù)據(jù)及時(shí)可靠的話,可以使用這種模式。

    這里要吐槽一句,不要看到select就說不會(huì)加鎖了,在Serializable這個(gè)級(jí)別,還是會(huì)加鎖的!

    聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    MySql的隔離級(jí)別和鎖的關(guān)系_MySQL

    MySql的隔離級(jí)別和鎖的關(guān)系_MySQL:一、事務(wù)的4個(gè)基本特征 Atomic(原子性): 事務(wù)中包含的操作被看做一個(gè)邏輯單元,這個(gè)邏輯單元中的操作要 么全部成功,要么全部失敗。 Consistency(一致性): 只有合法的數(shù)據(jù)可以被寫入數(shù)據(jù)庫(kù),否則事務(wù)應(yīng)該將其回滾到最初 狀態(tài)。 Isolation
    推薦度:
    標(biāo)簽: 關(guān)系 級(jí)別 mysql
    • 熱門焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产精品无码久久四虎| 亚洲精品国产av成拍色拍| 四虎影视永久在线精品| 国产精品一区二区久久精品| 亚洲精品无码久久久久去q| 国产精品国产三级在线高清观看| www.亚洲精品| 国产精品对白刺激久久久| 亚洲色精品88色婷婷七月丁香 | 午夜亚洲av永久无码精品| 成人国产精品一区二区视频| 国产小视频国产精品| 国产精品污WWW在线观看| 亚洲国产精品无码专区在线观看| 日韩精品视频在线观看免费 | 亚洲精品免费观看| 久久精品国产亚洲欧美| 成人精品视频在线观看| 精品人妻人人做人人爽| 久久国产精品无码一区二区三区| 亚洲精品你懂的在线观看 | 精品久久久久久综合日本| 97热久久免费频精品99| 国产成人精品日本亚洲11| 大桥未久在线精品视频在线| 国产精品你懂得| 久久福利青草精品资源站免费| 麻豆精品久久精品色综合| 亚洲精品综合一二三区在线| 99久久精品免费观看国产| 国产福利精品在线观看| 国产精品成人国产乱一区| 精品国产一区二区三区在线观看 | 无码少妇精品一区二区免费动态 | 久久99国产综合精品女同| 久久精品人人做人人爽97| 国产精品兄妹在线观看麻豆| 99在线精品视频观看免费| 久久精品国产福利国产秒| 99精品国产福利在线观看| 国产成人精品在线观看|