MySQL中的悲觀鎖

什么是悲觀鎖

關(guān)系數(shù)據(jù)庫管理系統(tǒng)里啥箭,悲觀并發(fā)控制(又名“悲觀鎖”酒繁,Pessimistic Concurrency Control皮钠,縮寫“PCC”)是一種并發(fā)控制的方法识樱。它可以阻止一個(gè)事務(wù)以影響其他用戶的方式來修改數(shù)據(jù)。如果一個(gè)事務(wù)執(zhí)行的操作讀某行數(shù)據(jù)應(yīng)用了鎖猴贰,那只有當(dāng)這個(gè)事務(wù)把鎖釋放对雪,其他事務(wù)才能夠執(zhí)行與該鎖沖突的操作。

悲觀并發(fā)控制主要用于數(shù)據(jù)爭(zhēng)用激烈的環(huán)境米绕,以及發(fā)生并發(fā)沖突時(shí)使用鎖保護(hù)數(shù)據(jù)的成本要低于回滾事務(wù)的成本的環(huán)境中瑟捣。

簡(jiǎn)而言之,悲觀鎖主要用于保護(hù)數(shù)據(jù)的完整性栅干。當(dāng)多個(gè)事務(wù)并發(fā)執(zhí)行時(shí)迈套,某個(gè)事務(wù)對(duì)數(shù)據(jù)應(yīng)用了鎖,則其他事務(wù)只能等該事務(wù)執(zhí)行完了碱鳞,才能進(jìn)行對(duì)該數(shù)據(jù)進(jìn)行修改操作桑李。

使用場(chǎng)景

在商品購(gòu)買場(chǎng)景中,當(dāng)有多個(gè)用戶對(duì)某個(gè)庫存有限的商品同時(shí)進(jìn)行下單操作窿给。若采用先查詢庫存贵白,后減庫存的方式進(jìn)行庫存數(shù)量的變更,將會(huì)導(dǎo)致超賣的產(chǎn)生崩泡。

商品超賣流程圖

若使用悲觀鎖禁荒,當(dāng)B用戶獲取到某個(gè)商品的庫存數(shù)據(jù)時(shí),用戶A則會(huì)阻塞角撞,直到B用戶完成減庫存的整個(gè)事務(wù)時(shí)圈浇,A用戶才可以獲取到商品的庫存數(shù)據(jù)。則可以避免商品被超賣靴寂。

如何使用悲觀鎖

用法:SELECT … FOR UPDATE;

例如,

select * from tbl_user where id=1 for update;

獲取鎖的前提:結(jié)果集中的數(shù)據(jù)沒有使用排他鎖或共享鎖時(shí)召耘,才能獲取鎖百炬,否則將會(huì)阻塞。

需要注意的是污它, FOR UPDATE 生效需要同時(shí)滿足兩個(gè)條件時(shí)才生效:

  • 數(shù)據(jù)庫的引擎為 innoDB
  • 操作位于事務(wù)塊中(BEGIN/COMMIT)

體驗(yàn)悲觀鎖

Step 1 初始化表結(jié)構(gòu)和數(shù)據(jù)

CREATE TABLE `tbl_user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `status` int(11) DEFAULT NULL,
  `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
);


INSERT INTO `tbl_user` (`id`, `status`, `name`)
VALUES
    (1,1,X'7469616E'),
    (2,1,X'63697479');

Step 2

窗口1

// 關(guān)閉mysql數(shù)據(jù)庫的自動(dòng)提交屬性
set autocommit=0;

// 開啟事務(wù)
BEGIN;

SELECT * FROM tbl_user where id=1 for update;

窗口2

此時(shí)剖踊,我們?cè)诖翱?執(zhí)行下面這條命令庶弃,嘗試獲取悲觀鎖:

SELECT * FROM tbl_user where id=1 for update;

執(zhí)行完后,窗口2并沒有像窗口1一樣德澈,立刻返回結(jié)果歇攻,而是發(fā)生了阻塞。

若超時(shí)間未獲取鎖梆造,將會(huì)得到一個(gè)鎖超時(shí)錯(cuò)誤提示缴守。如下圖所示:


獲取鎖超時(shí)

行鎖與表鎖

當(dāng)執(zhí)行 select ... for update時(shí),將會(huì)把數(shù)據(jù)鎖住镇辉,因此屡穗,我們需要注意一下鎖的級(jí)別。MySQL InnoDB 默認(rèn)為行級(jí)鎖忽肛。當(dāng)查詢語句指定了主鍵時(shí)村砂,MySQL會(huì)執(zhí)行「行級(jí)鎖」,否則MySQL會(huì)執(zhí)行「表鎖」屹逛。

常見情況如下:

  • 若明確指明主鍵础废,且結(jié)果集有數(shù)據(jù),行鎖罕模;
  • 若明確指明主鍵评腺,結(jié)果集無數(shù)據(jù),則無鎖手销;
  • 若無主鍵歇僧,且非主鍵字段無索引,則表鎖锋拖;
  • 若使用主鍵但主鍵不明確诈悍,則使用表鎖;
select * from tbl_user where id<>1 for update; 

若需要了解更多情況兽埃,可以閱讀 此篇文章了解更多侥钳。

小結(jié): innoDB的行鎖是通過給索引上的索引項(xiàng)加鎖實(shí)現(xiàn)的,因此柄错,只有通過索引檢索數(shù)據(jù)舷夺,才會(huì)采用行鎖,否則使用的是表鎖售貌。

總結(jié)

悲觀鎖采用的是「先獲取鎖再訪問」的策略给猾,來保障數(shù)據(jù)的安全。但是加鎖策略颂跨,依賴數(shù)據(jù)庫實(shí)現(xiàn)敢伸,會(huì)增加數(shù)據(jù)庫的負(fù)擔(dān),且會(huì)增加死鎖的發(fā)生幾率恒削。此外池颈,對(duì)于不會(huì)發(fā)生變化的只讀數(shù)據(jù)尾序,加鎖只會(huì)增加額外不必要的負(fù)擔(dān)。在實(shí)際的實(shí)踐中躯砰,對(duì)于并發(fā)很高的場(chǎng)景并不會(huì)使用悲觀鎖每币,因?yàn)楫?dāng)一個(gè)事務(wù)鎖住了數(shù)據(jù),那么其他事務(wù)都會(huì)發(fā)生阻塞琢歇,會(huì)導(dǎo)致大量的事務(wù)發(fā)生積壓拖垮整個(gè)系統(tǒng)兰怠。

參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市矿微,隨后出現(xiàn)的幾起案子痕慢,更是在濱河造成了極大的恐慌,老刑警劉巖涌矢,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掖举,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡娜庇,警方通過查閱死者的電腦和手機(jī)塔次,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來名秀,“玉大人励负,你說我怎么就攤上這事∝暗茫” “怎么了继榆?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)汁掠。 經(jīng)常有香客問我略吨,道長(zhǎng),這世上最難降的妖魔是什么考阱? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任翠忠,我火速辦了婚禮,結(jié)果婚禮上乞榨,老公的妹妹穿的比我還像新娘秽之。我一直安慰自己,他們只是感情好吃既,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布考榨。 她就那樣靜靜地躺著,像睡著了一般鹦倚。 火紅的嫁衣襯著肌膚如雪董虱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音愤诱,去河邊找鬼。 笑死捐友,一個(gè)胖子當(dāng)著我的面吹牛淫半,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匣砖,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼科吭,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了猴鲫?” 一聲冷哼從身側(cè)響起对人,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拂共,沒想到半個(gè)月后牺弄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宜狐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年势告,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抚恒。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咱台,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出俭驮,到底是詐尸還是另有隱情回溺,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布混萝,位于F島的核電站遗遵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏譬圣。R本人自食惡果不足惜瓮恭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厘熟。 院中可真熱鬧屯蹦,春花似錦、人聲如沸绳姨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽飘庄。三九已至脑蠕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谴仙。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工迂求, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晃跺。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓揩局,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親掀虎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凌盯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容