「MySQL高級篇」MySQL鎖機制 && 事務

大家好 , 我是melo,一名大三后臺練習生,最近趕在春招前整理整理發過的博客~!
引言鎖鎖鎖,到哪到離不開這樁瑣事,并發瑣事,redis瑣事 , 如今是MySQL瑣事 , 這其中瑣事,還跟MySQL另一個重要的東西--事務息息相關 。
「MySQL高級篇」MySQL鎖機制 && 事務

文章插圖
這篇將從以下幾點 , 帶你解開這把愛情的苦鎖:
本篇速覽腦圖
「MySQL高級篇」MySQL鎖機制 && 事務

文章插圖
常規表鎖&行鎖
這一部分較為常規 , 若有前置知識,可以直接跳到下邊的【表級鎖擴展】部分開始閱讀建議借助側邊欄 , 有emoji表情的屬于重點
鎖概述鎖是計算機協調多個進程或線程并發訪問某一資源的機制(避免爭搶) 。
在數據庫中,除傳統的計算資源(如 CPU、RAM、I/O 等)的爭用以外,數據也是一種供許多用戶共享的資源 。如何保證數據并發訪問的一致性、有效性是所有數據庫必須解決的一個問題 , 鎖沖突也是影響數據庫并發訪問性能的一個重要因素 。從這個角度來說,鎖對數據庫而言顯得尤其重要,也更加復雜 。
鎖分類從對數據操作的粒度分 :
1) 表鎖:操作時,會鎖定整個表 。
2) 行鎖:操作時 , 會鎖定當前操作行 。
從對數據操作的類型分:
1) 讀鎖(共享鎖):針對同一份數據,多個讀操作可以同時進行而不會互相影響 。
2) 寫鎖(排它鎖):當前操作沒有完成之前,它會阻斷其他寫鎖和讀鎖 。
Mysql 鎖相對其他數據庫而言,MySQL的鎖機制比較簡單,其最顯著的特點是不同的存儲引擎支持不同的鎖機制 。下表中羅列出了各存儲引擎對鎖的支持情況:
存儲引擎表級鎖行級鎖頁面鎖(了解)MyISAM支持不支持不支持InnoDB支持支持(默認)不支持MEMORY支持不支持不支持BDB支持不支持支持MySQL這3種鎖的特性可大致歸納如下 :
鎖類型特點表級鎖偏向MyISAM 存儲引擎,開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,并發度最低 。行級鎖偏向InnoDB 存儲引擎,開銷大,加鎖慢;會出現死鎖;鎖定粒度最??,发生锁冲蛪哪概率最?并發度也最高 。頁面鎖開銷和加鎖時間界于表鎖和行鎖之間;會出現死鎖;鎖定粒度界于表鎖和行鎖之間 , 并發度一般 。
粒度小 , 自然發生鎖沖突的概率就低
從上述特點可見,很難籠統地說哪種鎖更好,只能就具體應用的特點來說哪種鎖更合適!
僅從鎖的角度來說:表級鎖更適合于以查詢為主 , 只有少量按索引條件更新數據的應用 , 如Web 應用;
而行級鎖則更適合于有大量按索引條件并發更新少量不同數據 , 同時又有并查詢的應用 , 如一些在線事務處理(OLTP)系統 。
MyISAM 表鎖MyISAM 存儲引擎只支持表鎖,這也是MySQL開始幾個版本中唯一支持的鎖類型 。
如何加表鎖MyISAM 在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執行更新操作(UPDATE、DELETE、INSERT 等)前,會自動給涉及的表加寫鎖,這個過程并不需要用戶干預,因此,用戶一般不需要直接用 LOCK TABLE 命令給 MyISAM 表顯式加鎖 。
顯示加表鎖語法:
加讀鎖 : lock table table_name read;加寫鎖 : lock table table_name write;讀鎖案例準備環境
create database demo_03 default charset=utf8mb4;use demo_03;CREATE TABLE `tb_book` (`id` INT(11) auto_increment,`name` VARCHAR(50) DEFAULT NULL,`publish_time` DATE DEFAULT NULL,`status` CHAR(1) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=myisam DEFAULT CHARSET=utf8 ;INSERT INTO tb_book (id, name, publish_time, status) VALUES(NULL,'java編程思想','2088-08-01','1');INSERT INTO tb_book (id, name, publish_time, status) VALUES(NULL,'solr編程思想','2088-08-08','0');CREATE TABLE `tb_user` (`id` INT(11) auto_increment,`name` VARCHAR(50) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=myisam DEFAULT CHARSET=utf8 ;INSERT INTO tb_user (id, name) VALUES(NULL,'令狐沖');INSERT INTO tb_user (id, name) VALUES(NULL,'田伯光');讀操作客戶端一對book表加了鎖,并拿到了book表的鎖,在該鎖未釋放之前,不能去查別的表;而客戶端二能查到book和其他表,是因為讀鎖是共享鎖,他并沒有真正拿到這把鎖,自然可以肆意妄為 , 不受未釋放鎖的束縛;
「MySQL高級篇」MySQL鎖機制 && 事務

文章插圖

推薦閱讀