MySQL 死鎖產(chǎn)生原因及解決方法

死鎖報(bào)錯日志:

Deadlock found when trying to get lock; try restarting transaction

死鎖報(bào)錯示例:

1、各自鎖住對方進(jìn)程正在使用的行數(shù)據(jù)
譬如先執(zhí)行:

-- session1
BEGIN;
UPDATE students SET memo='DLLock' WHERE dbid =9;
-- session2
BEGIN;
UPDATE students SET memo='DLLock' WHERE dbid =7;

再執(zhí)行:

-- session1
UPDATE students SET memo='DLLock' WHERE dbid =7;
-- session2
UPDATE students SET memo='DLLock' WHERE dbid =9;

再比如下面的情況:

-- session1
BEGIN;
UPDATE students SET memo='DLLock' WHERE dbid =9;
-- session2
BEGIN;
SELECT dbid FROM students WHERE dbid<20 for UPDATE;

執(zhí)行完以上后再在session1中執(zhí)行如下区匠,即可產(chǎn)生死鎖:

UPDATE students SET memo='DdLock' WHERE dbid =1;

因?yàn)閟ession2中的 dbid<20 會先對小于9的數(shù)據(jù)先加鎖(id-9已經(jīng)被session1提前加鎖)巩掺,此時(shí)session1再對id-1的數(shù)據(jù)執(zhí)行加鎖,就會產(chǎn)生爭用睬愤,從而產(chǎn)生死鎖待榔。

2屁使、批量入庫减细,不存在則新增匆瓜,存在則更新的情況:
假設(shè)目前 students 表中不存在 dbid 為 19 和 20 的數(shù)據(jù),此時(shí)需要新增

-- session1
BEGIN;
SELECT * FROM students WHERE dbid =19 for UPDATE;
-- session2
BEGIN;
SELECT * FROM students WHERE dbid =20 for UPDATE;

執(zhí)行完以上后再在各自的session中中執(zhí)行插入操作未蝌,即可產(chǎn)生死鎖:

-- session1
INSERT INTO `students` (`dbid`, `uid`, `uname`) VALUES (19, 39, '小明明');
-- session2
INSERT INTO `students` (`dbid`, `uid`, `uname`) VALUES (20, 35, '小紅紅');

為何兩條不存在的數(shù)據(jù)也會產(chǎn)生死鎖驮吱,是因?yàn)椋?/p>

  • 當(dāng)對已存在的行進(jìn)行鎖定時(shí)(主鍵),mysql就只有行鎖萧吠。
  • 當(dāng)對未存在的行進(jìn)行鎖的時(shí)候(即使條件為主鍵)左冬,mysql會鎖住一段范圍(即gap鎖),其鎖范圍為:
    (無窮小或小于表中鎖住id的最大值纸型,無窮大或大于表中鎖住id的最小值)

如果表中目前有已有的id為18拇砰,那么就鎖住 [19,無窮大);
如果表中目前已有的 id 區(qū)間為(11 狰腌, 30)毕匀,那么就鎖住[12,29]癌别;
所以示例2中的兩個session其實(shí)鎖住的是相同 gap 中的數(shù)據(jù),因此執(zhí)行插入時(shí)才會產(chǎn)生 dead-lock蹋笼;對于這種此類示例2的死鎖解決辦法是用mysql特有的語法 ON DUPLICATE KEY UPDATE來解決此問題展姐;
該語法的意思為:

  • 在insert時(shí)候,如果insert的數(shù)據(jù)會引起唯一索引(包括主鍵索引)的沖突剖毯,即唯一值重復(fù)了圾笨,則不會執(zhí)行insert操作,而執(zhí)行后面的update操作逊谋。

如下兩條語句最終的執(zhí)行效果相同:

-- 1
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;  
-- 2
UPDATE table SET c=c+1 WHERE a=1;

因?yàn)橄鄬τ谥麈I來說擂达,insert語句,插入的行不管是否存在胶滋,都只有行鎖板鬓。


就到這里吧悲敷!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市俭令,隨后出現(xiàn)的幾起案子后德,更是在濱河造成了極大的恐慌,老刑警劉巖抄腔,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓢湃,死亡現(xiàn)場離奇詭異,居然都是意外死亡赫蛇,警方通過查閱死者的電腦和手機(jī)绵患,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悟耘,“玉大人落蝙,你說我怎么就攤上這事∽骰停” “怎么了掘殴?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長粟誓。 經(jīng)常有香客問我奏寨,道長,這世上最難降的妖魔是什么鹰服? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任病瞳,我火速辦了婚禮,結(jié)果婚禮上悲酷,老公的妹妹穿的比我還像新娘套菜。我一直安慰自己,他們只是感情好设易,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布逗柴。 她就那樣靜靜地躺著,像睡著了一般顿肺。 火紅的嫁衣襯著肌膚如雪戏溺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天屠尊,我揣著相機(jī)與錄音旷祸,去河邊找鬼。 笑死讼昆,一個胖子當(dāng)著我的面吹牛托享,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼闰围,長吁一口氣:“原來是場噩夢啊……” “哼赃绊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辫诅,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凭戴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后炕矮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體么夫,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年肤视,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了档痪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡邢滑,死狀恐怖腐螟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情困后,我是刑警寧澤乐纸,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站摇予,受9級特大地震影響汽绢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜侧戴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一宁昭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酗宋,春花似錦积仗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至回右,卻和暖如春稀颁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背楣黍。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棱烂,地道東北人租漂。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哩治。 傳聞我的和親對象是個殘疾皇子秃踩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評論 2 359

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