<input id="ohw05"></input>
  • <table id="ohw05"><menu id="ohw05"></menu></table>
  • <var id="ohw05"></var>
  • <code id="ohw05"><cite id="ohw05"></cite></code>
    <label id="ohw05"></label>
    <var id="ohw05"></var>
  • MySQL十種鎖,一篇文章帶你全解析

    MySQL有兩個核心的知識點,索引和鎖。前幾篇文章已經詳細講解了MySQL索引實現機制,今天再一起學習一下MySQL的鎖。

    1 為什么要加鎖?

    當多個事務并發操作同一批數據的時候,如果不加鎖,就無法保證事務的隔離性,最后導致數據錯亂。

    加鎖是為了保證并發操作下數據的正確性。

    2 鎖的分類有哪些?

    按鎖的粒度可分為:表鎖、頁面鎖、行鎖、記錄鎖、間隙鎖、臨鍵鎖

    按鎖的屬性可分為:共享鎖、排它鎖

    按加鎖機制可分為:樂觀鎖、悲觀鎖

    下面依次介紹一下這幾種鎖:

    表鎖:

    MyISAM和InnoDB引擎均支持表鎖。

    優點:開銷小,加鎖快,不會出現死鎖。

    缺點:鎖定力度大,發生鎖沖突概率高,并發度最低。

    加鎖方式:

    # 對user表加讀鎖
    lock table user read;
    # 同時對user表加讀鎖,對order表加寫鎖
    lock tables user read, order write;
    

    什么情況下需要用到表鎖?

    1. 當需要更新表中的大部分數據
    2. 事務涉及到多張表,業務邏輯復雜,加表鎖可以避免死鎖。

    頁面鎖:

    優點:開銷和加鎖速度介于表鎖和行鎖之間。

    缺點:會出現死鎖,鎖定粒度介于表鎖和行鎖之間,并發度一般。

    目前只有BDB引擎支持頁面鎖,應用場景較少。

    行鎖:

    只有InnoDB引擎支持行鎖,另外鎖是加在索引上面的。

    優點: 開銷大,加鎖慢;會出現死鎖。

    缺點:鎖定粒度小,發生鎖沖突的概率低,并發度高。

    另外記錄鎖、間隙鎖、臨鍵鎖均屬于行鎖。

    記錄鎖(Record Locks):

    即對某條記錄加鎖。

    # 對id=1的用戶加鎖
    update user set age=age+1 where id=1;
    

    間隙鎖(Gap Locks):

    即對某個范圍加鎖,但是不包含范圍的臨界數據。

    # 對id大于1并且小于10的用戶加鎖
    update user set age=age+1 where id>1 and id<10;
    

    上面SQL的加鎖范圍是(1,10)。

    臨鍵鎖(Next-Key Locks):

    由記錄鎖和間隙鎖組成,既包含記錄本身又包含范圍,左開右閉區間。

    # 對id大于1并且小于等于10的用戶加鎖
    update user set age=age+1 where id>1 and id<=10;
    

    共享鎖(又稱讀鎖、S鎖):

    作用:防止其他事務修改當前數據。

    加鎖方式:

    在select語句末尾加上lock in share mode關鍵字。

    # 對id=1的用戶加讀鎖
    select * from user where id=1 lock in share mode;
    

    排他鎖(又稱寫鎖、X鎖):

    作用:防止其他事務讀取或者更新當前數據。

    加鎖方式:

    在select語句末尾加上for update關鍵字。

    # 對id=1的用戶加寫鎖
    select * from user where id=1 for update;
    

    樂觀鎖:

    總是假設別人不會修改當前數據,所以每次讀取數據的時候都不會加鎖,只是在更新數據的時候通過version判斷別人是否修改過數據,Java的atomic包下的類就是使用樂觀鎖(CAS)實現的。

    適用于讀多寫少的場景。

    加鎖方式:

    1. 讀取version

      select id,name,age,version from user id=1;
      
    2. 更新數據,判斷version是否修改過。

      update user set age=age+1 where id=1 and version=1;
      

    悲觀鎖:

    總是假設別人會修改當前數據,所以每次讀取的時候,總是加鎖。

    適用于寫多讀少的場景。

    加鎖方式:

    # 加讀鎖
    select * from user where id=1 lock in share mode;
    # 加寫鎖
    select * from user where id=1 for update;
    

    本文知識點總結:

    文章持續更新,可以微信搜一搜「 一燈架構 」第一時間閱讀更多技術干貨。

    posted @ 2022-06-27 22:22  一燈架構  閱讀(369)  評論(3編輯  收藏  舉報
    公眾號:一燈架構 大廠開發專家,只分享有趣的技術干貨。
    国产美女a做受大片观看