一文帶你了解MySQL中的鎖機(jī)制
目錄
- 一.概述
- 分類(lèi)
- 二.MyISAM表鎖
- 如何加表鎖
- 寫(xiě)鎖演示
- 三.InnoDB行鎖
- 行鎖特點(diǎn)
一.概述
鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問(wèn)某一資源的機(jī)制(避免爭(zhēng)搶?zhuān)?/p>
在數(shù)據(jù)庫(kù)中,除傳統(tǒng)的計(jì)算資源(如CPU、RAM、I/O等)的爭(zhēng)用以外,數(shù)據(jù)也是一種供許多用戶(hù)共享的資如何保證數(shù)據(jù)并發(fā)訪問(wèn)的一致性、有效性是所有數(shù)據(jù)庫(kù)必須解決的一個(gè)問(wèn)題,鎖沖突也是影響數(shù)據(jù)庫(kù)并發(fā)訪問(wèn)性能的一個(gè)重要因素。從這個(gè)角度來(lái)說(shuō),鎖對(duì)數(shù)據(jù)庫(kù)而言顯得尤其重要,也更加復(fù)雜。
分類(lèi)
1、從對(duì)數(shù)據(jù)操作的粒度分
- 表鎖:操作時(shí),會(huì)鎖定整個(gè)表。
- 行鎖:操作時(shí),會(huì)鎖定當(dāng)前操作行。
2、從對(duì)數(shù)據(jù)操作的類(lèi)型分
- 讀鎖(共享鎖):針對(duì)同一份數(shù)據(jù),多個(gè)讀操作可以同時(shí)進(jìn)行而不會(huì)互相影響。
- 寫(xiě)鎖(排它鎖):當(dāng)前操作沒(méi)有完成之前,它會(huì)阻斷其他寫(xiě)鎖和讀鎖。
相對(duì)其他數(shù)據(jù)庫(kù)而言,MySQL的鎖機(jī)制比較簡(jiǎn)單,其最顯著的特點(diǎn)是不同的存儲(chǔ)引擎支持不同的鎖機(jī)制。下表中羅列出了各存儲(chǔ)引擎對(duì)鎖的支持情況:
存儲(chǔ)引擎表級(jí)鎖行級(jí)鎖MylSAM支持不支持lnnoDB支持支持MEMORY支持不支持BDB支持不支持MySQL鎖的特性可大致歸納如下:
鎖類(lèi)型特點(diǎn)表級(jí)鎖偏向MyISAM存儲(chǔ)引擎,開(kāi)銷(xiāo)小,加鎖快;不會(huì)出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。行級(jí)鎖偏向InnoDB存儲(chǔ)引擎,開(kāi)銷(xiāo)大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。從上述特點(diǎn)可見(jiàn),很難籠統(tǒng)地說(shuō)哪種鎖更好,只能就具體應(yīng)用的特點(diǎn)來(lái)說(shuō)哪種鎖更合適! 僅從鎖的角度來(lái)說(shuō):表級(jí)鎖更適合于以查詢(xún)?yōu)橹鳎挥猩倭堪此饕龡l件更新數(shù)據(jù)的應(yīng)用,如web應(yīng)用;
而行級(jí)鎖則更適合于有大量按索引條件并發(fā)更新少量不同數(shù)據(jù),同時(shí)又有并查詢(xún)的應(yīng)用,如一些在線事務(wù)處理(OLTP)系統(tǒng)。
二.MyISAM表鎖
MylSAM存儲(chǔ)引擎只支持表鎖
如何加表鎖
MylSAM在執(zhí)行查詢(xún)語(yǔ)句(SELECT)前,會(huì)自動(dòng)給涉及的所有表加讀鎖,在執(zhí)行更新操作(UPDATE、DELETE、INSERT等)前,會(huì)自動(dòng)給涉及的表加寫(xiě)鎖,這個(gè)過(guò)程并不需要用戶(hù)干預(yù),因此,用戶(hù)一般不需要直接用LOCK TABLE命令給MylSAM表顯式加鎖。
讀鎖演示
create database test_lock;use test_lock; drop table tb_book ; 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 values(null,"sql","2088-08-01","1");insert into tb_book values(null,"sql",20880908,"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 values(null,"張三");insert into tb_user values(null,"李四"); -- 加讀鎖lock table tb_book read; select * from tb_book ;-- 能正常輸出select * from tb_book tb ;-- 不能正常輸出,不能有別名update tb_book set status=1;-- 不能正常輸出 讀鎖:可讀不可改 select * from tb_user ;-- 不能正常輸出,當(dāng)鎖住一個(gè)表時(shí)也不能看其他表-- 解鎖unlock tables;
加了讀鎖后只能看自己的表,不能修改,也不能看其他的表
寫(xiě)鎖演示
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 values(null,"sql","2088-08-01","1");insert into tb_book values(null,"sql",20880908,"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 values(null,"張三");insert into tb_user values(null,"李四"); -- 加寫(xiě)鎖lock table tb_book write; select * from tb_book ;-- 能正常輸出select * from tb_book tb ;-- 不能正常輸出,不能有別名update tb_book set status=1;-- 可以修改 寫(xiě)鎖:可讀可修改,但在沒(méi)有解鎖之前不能被其他人查看,會(huì)被掛起 select * from tb_user ;-- 不能正常輸出,當(dāng)鎖住一個(gè)表時(shí)也不能看其他表-- 解鎖unlock tables;
三.InnoDB行鎖
行鎖特點(diǎn)
行鎖特點(diǎn)︰偏向InnoDB存儲(chǔ)引擎,開(kāi)銷(xiāo)大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。
InnoDB與 MylSAM的最大不同有兩點(diǎn):一是支持事務(wù);二是采用了行級(jí)鎖。
行鎖模式
lnnoDB實(shí)現(xiàn)了以下兩種類(lèi)型的行鎖。
1、共享鎖(S)∶又稱(chēng)為讀鎖,簡(jiǎn)稱(chēng)s鎖,共享鎖就是多個(gè)事務(wù)對(duì)于同一數(shù)據(jù)可以共享一把鎖,都能訪問(wèn)到數(shù)據(jù),但是只能讀不能修改。
2、排他鎖(x):又稱(chēng)為寫(xiě)鎖,簡(jiǎn)稱(chēng)x鎖,排他鎖就是不能與其他鎖并存,如一個(gè)事務(wù)獲取了一個(gè)數(shù)據(jù)行的排他鎖,其他事務(wù)就不能再獲取該行的其他鎖,包括共享鎖和排他鎖,但是獲取排他鎖的事務(wù)是可以對(duì)數(shù)據(jù)就行讀取和修改。
對(duì)于UPDATE、DELETE和INSERT語(yǔ)句,InnoDB會(huì)自動(dòng)給涉及數(shù)據(jù)集加排他鎖(x);
對(duì)于普通SELECT語(yǔ)句,InnoDB不會(huì)加任何鎖;
可以通過(guò)以下語(yǔ)句顯示給記錄集加共享鎖或排他鎖。
-- 行鎖 drop table is exists test_innodb_lock;create table test_innodb_lock( id int(11), name varchar(16), sex varchar(1))engine=innodb; insert into test_innodb_lock values(1,"100","1"), (2,"200","0"), (3,"200","1"), (4,"300","0"), (5,"400","0"), (6,"500","1"), (7,"600","1"), (1,"700","1"); create index index_id on test_innodb_lock(id);create index index_name on test_innodb_lock(name);
可以修改是因?yàn)樯厦娴男墟i只對(duì)id=1的那兩行加了排他鎖
到此這篇關(guān)于一文帶你了解MySQL中的鎖機(jī)制的文章就介紹到這了,更多相關(guān)MySQL鎖機(jī)制內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!
