<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MySQL 事務(wù)隔離級別實現(xiàn)原理和鎖的關(guān)系

          共 2637字,需瀏覽 6分鐘

           ·

          2022-01-02 02:38

          隔離級別

          并發(fā)帶來的問題
          • 臟讀(dirty read)

          如果一個事務(wù)讀到了另一個未提交事務(wù)修改過的數(shù)據(jù),如果另一個事務(wù)發(fā)生了回滾,那么該數(shù)據(jù)就是臟數(shù)據(jù)。

          • 不可重復(fù)讀(non-repeatable read)

          如果一個事務(wù)只能讀到另一個已經(jīng)提交的事務(wù)修改過的數(shù)據(jù),并且其他事務(wù)每對該數(shù)據(jù)進(jìn)行一次修改并提交后,該事務(wù)都能查詢得到最新值,即一個事務(wù)里兩次查詢一個數(shù)據(jù)的結(jié)果不一樣。。

          • 幻讀(phantom read)

          如果一個事務(wù)先根據(jù)某些條件查詢出一些記錄,之后另一個事務(wù)又向表中插入了符合這些條件的記錄,原先的事務(wù)再次按照該條件查詢時,能把另一個事務(wù)插入的記錄也讀出來。

          注意

          • 臟讀側(cè)重是未提交事務(wù)的數(shù)據(jù)。
          • 而不可重復(fù)讀和幻讀都是讀到了已提交的數(shù)據(jù),但不可重復(fù)讀重點在于update和delete,而幻讀的重點在于insert。

          四種隔離級別

          實現(xiàn)原理

          MVCC

          首先,在介紹實現(xiàn)原理之前先簡單的介紹一下MySQL的MVCC機(jī)制。

          悲觀鎖和樂觀鎖

          悲觀鎖

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

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

          樂觀鎖

          相對悲觀鎖而言,樂觀鎖機(jī)制采取了更加寬松的加鎖機(jī)制。悲觀鎖大多數(shù)情況下依靠數(shù)據(jù)庫的鎖機(jī)制實現(xiàn),以保證操作最大程度的獨占性。但隨之而來的就是數(shù)據(jù)庫性能的大量開銷,特別是對長事務(wù)而言,這樣的開銷往往無法承受。而樂觀鎖機(jī)制在一定程度上解決了這個問題。

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

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

          MVCC在MySQL中的實現(xiàn)

          所謂的MVCC(Multi-Version Concurrency Control ,多版本并發(fā)控制)指的就是在使用讀已提交(READ COMMITTD)、可重復(fù)讀(REPEATABLE READ)這兩種隔離級別的事務(wù)在執(zhí)行普通的SELECT操作時訪問記錄的版本鏈的過程,這樣子可以使不同事務(wù)的讀-寫、寫-讀操作并發(fā)執(zhí)行,從而提升系統(tǒng)性能。

          • SELECT時,讀取創(chuàng)建版本號<=當(dāng)前事務(wù)版本號,刪除版本號為空或>當(dāng)前事務(wù)版本號。
          • INSERT時,保存當(dāng)前事務(wù)版本號為行的創(chuàng)建版本號
          • DELETE時,保存當(dāng)前事務(wù)版本號為行的刪除版本號
          • UPDATE時,插入一條新紀(jì)錄,保存當(dāng)前事務(wù)版本號為行創(chuàng)建版本號,同時保存當(dāng)前事務(wù)版本號到原來刪除的行
          快照讀與當(dāng)前讀

          快照讀:就是select

          select?*?from?table?….;

          當(dāng)前讀:特殊的讀操作,插入/更新/刪除操作,屬于當(dāng)前讀,處理的都是當(dāng)前的數(shù)據(jù),需要加鎖。

          select?*?from?table?where???lock?in?share?mode;
          select?*?from?table?where???for?update;
          insert;
          update?;
          delete;

          ReadView

          InnoDB在實現(xiàn)MVCC時用到的一致性讀視圖,即consistent read view,用于支持RC(Read Committed,讀提交)和RR(Repeatable Read,可重復(fù)讀)隔離級別的實現(xiàn)。具體實現(xiàn)可見

          讀未提交Read Uncommitted

          不做任何加鎖和MVCC操作。

          讀提交Read Committed
          • 對于讀操作,不加鎖,為快照讀,每次讀取都使用最新的事務(wù)版本號生成最新的ReadView。
          • 對于寫操作,每次加行鎖(提交事務(wù)時才解鎖,并且更新數(shù)據(jù)庫的事務(wù)版本)。

          這樣的話就解決了臟讀問題,只要事務(wù)沒提交,數(shù)據(jù)庫的事務(wù)版本號就不會更新,那么ReadView中的數(shù)據(jù)永遠(yuǎn)都是這個新事務(wù)之前的數(shù)據(jù)。

          但是沒有解決不可重復(fù)讀的問題,因為一個事務(wù)內(nèi)每次查詢的ReadView版本不一致。

          可重復(fù)讀Repeatable Read
          • 對于讀操作,不加鎖,只有第一次讀取的時候才會生成一個ReadView。
          • 對于寫操作,加臨鍵鎖Next-key鎖(行鎖+GAP間隙鎖),就是除了給當(dāng)行記錄加鎖,還會給當(dāng)行記錄周圍區(qū)間加間隙鎖。

          ReadView不同的生成策略解決了不可重復(fù)讀的問題,由于一個事務(wù)內(nèi)用的都是第一次查詢的ReadView,所以查出來的數(shù)據(jù)都是一致的。

          而Next-key鎖機(jī)制又在一定程度上解決了幻讀的問題,由于GAP鎖會把一些相鄰的區(qū)間也鎖上,那么插入時就會被阻塞,從而在一定程度上解決了幻讀的問題,但是又沒有完全解決,因為之后相距比較遠(yuǎn)的數(shù)據(jù)還是可以插入。

          串行讀Serializable
          • 悲觀鎖機(jī)制實現(xiàn)
          • 對于讀操作,加讀鎖。
          • 對于寫操作,加寫鎖。
          • 讀讀不互斥,讀寫互斥,寫寫互斥。
          • 由于讀寫互斥,完全解決了三個問題,但是并發(fā)度比較低。
          產(chǎn)生Gap間隙鎖的條件

          在可重復(fù)讀事務(wù)隔離級別下(該事務(wù)隔離級別間隙鎖才會生效)

          普通索引

          一定會產(chǎn)生間隙鎖

          唯一索引

          鎖定單行記錄

          • 對于指定查詢某一條記錄的加鎖語句,如果該記錄不存在,會產(chǎn)生記錄鎖和間隙鎖,如果記錄存在,則只會產(chǎn)生記錄鎖

          如:WHERE id = 5 FOR UPDATE;

          鎖定多行記錄

          • 對于查找某一范圍內(nèi)的查詢語句,會產(chǎn)生間隙鎖

          如:WHERE id BETWEEN 5 AND 7 FOR UPDATE;

          來源:blog.csdn.net/weixin_45563088/

          article/details/118641467

          瀏覽 21
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  做受 视频毛片丰满 | 熟女北条麻妃在线播放 | 澳门性爱视频 | 中文无码在线综合网 | 毛片基她 |