文章來源:51CTO博客,做者:青苔初生面試
一文讀懂全部鎖,瞭解他們的優缺點和使用場景。算法
table-level locking,鎖住整個表。sql
開銷小,加鎖快。數據庫
不會死鎖(一次性加載所需的全部表)。併發
鎖粒度大,發生鎖衝突機率大,併發效率低。學習
適合查詢。線程
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++和算法的優質內容,學習交流,技術探討,面試指導,簡歷修改...還有超多源碼素材等學習資料,零基礎的視頻等着你!
還沒關注的小夥伴,能夠長按關注一下: