一文讓你徹底搞懂 MySQL 的幾種鎖


文章來源:51CTO博客,作者:青苔初生

一文讀懂所有鎖,了解他們的優缺點和使用場景。

表級鎖與行級鎖

表級鎖:

table-level locking,鎖住整個表。

開銷小,加鎖快。

不會死鎖(一次性加載所需的所有表)。

鎖粒度大,發生鎖沖突概率大,並發效率低。

適合查詢。

行級鎖:

row-level loking,鎖住一行記錄。

開銷大,加鎖慢。

會死鎖。

鎖粒度小,發生所沖突概率小,並發效率高。

適合並發寫,事務控制。

並不是直接丟記錄行加鎖,而是對行對應的索引加鎖:

如果sql 語句操作了主鍵索引,Mysql 就會鎖定這條主鍵索引。

如果sql語句操作了非主鍵索引,MySQL會先鎖定該非主鍵索引,再鎖定相關的主鍵索引。

在InnoDB中,如果SQL語句不涉及索引,則會通過隱藏的聚簇索引來對記錄加鎖。

對聚簇索引加鎖,實際效果跟表鎖一樣,因為找到某一條記錄就得掃描全表,要掃描全表,就得鎖定表。

引擎與鎖:

MyISAM引擎支持表級鎖,不支持行級鎖。

InnoDB引擎支持表級鎖和行級鎖,默認為行級鎖。

共享鎖與排他鎖

共享鎖:

有稱之為S鎖、讀鎖。

當前線程對共享資源加共享鎖,其他線程可以讀取此資源、可以繼續追加共享鎖,但是不能修改此資源、不能追加排他鎖。

語法:select id from t_table in share mode;

多個共享鎖可以共存,共享鎖與排他鎖不能共存。

排他鎖:

又稱之為X鎖、寫鎖。

當前線程對共享資源加排他鎖,其他線程不允許讀取此資源,不允許追加共享鎖,不允許修改此資源,不允許追加排他鎖。

語法:

       1. update t_table set a =1; // 數據庫的增刪改操作默認都會加排他鎖

       2. select * from t_table for update;// for update也是一種增刪改

排他鎖是獨占的,不會與其他鎖共存。

樂觀鎖與悲觀鎖

樂觀鎖與悲觀鎖是邏輯上的鎖。

樂觀鎖:

樂觀鎖:樂觀地認為,並發問題很難發生。

樂觀鎖雖然認為並發問題很難發生,但並不是不會發生,所以也會有措施防止問題真的產生:每次數據修改都自增版本號version。

進行數據讀取時,並不加鎖,而是同時讀取當前的版本號version1;在對數據進行修改時,要判斷當前的版本號version2是否等於之前的版本號version1。

版本號不匹配,則代表着並發問題已產生,所以需要回滾此次操作。

實現方式:版本號機制、CAS。

悲觀鎖:

悲觀鎖:悲觀地認為,並發問題極易發生。

悲觀鎖認為並發問題極易發生,所以每次操作,無論讀寫,都會對記錄加鎖,以防止其他線程對數據進行修改。

實現方式:數據庫的行鎖、讀鎖和寫鎖。

最后,特別推薦一個分享C/C++和算法的優質內容,學習交流,技術探討,面試指導,簡歷修改...還有超多源碼素材等學習資料,零基礎的視頻等着你!

還沒關注的小伙伴,可以長按關注一下:


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM