Delete&Insert引發(fā)的Mysql死鎖

近日遇到一個比較奇怪的deadlock錯誤, 錯誤詳情:

Deadlock found when trying to get lock; try restarting transaction; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException...

跟蹤代碼后最終定位到一段業(yè)務(wù)邏輯:

delete from A where no = $no;
insert into A(no, value) values($no, "value");

印象中mysql一直是使用行級鎖, 為什么此處在并發(fā)時會發(fā)生死鎖呢? 唯一的解釋是mysql在這邊鎖住的不只一行數(shù)據(jù).

簡單搜索之后, 發(fā)現(xiàn)mysql的鎖分為三種(按照鎖定的行數(shù)劃分):
1.record lock:記錄鎖掌动,也就是僅僅鎖著單獨的一行
2.gap lock:區(qū)間鎖四啰,僅僅鎖住一個區(qū)間(注意這里的區(qū)間都是開區(qū)間,也就 是不包括邊界值粗恢,至于為什么這么定義柑晒?innodb官方定義的)
3.next-key lock:record lock+gap lock,所以next-key lock也就半開半閉區(qū)間眷射,且是下界開匙赞,上界閉。(為什么這么定義妖碉?innodb官方定義的)

由于此處是在明確指定了no=XX的情況下拋出了死鎖異常, 并且no建立的是普通索引, 所以此處mysql使用的應(yīng)該是next-key lock(查看何種情況下使用何種鎖 https://dev.mysql.com/doc/refman/5.7/en/innodb-locks-set.html).

下面來舉個手冊上的例子看看next-key lock是如何上鎖的涌庭。假如一個索引的行有10,11,13,20
那么可能的next-key lock的包括:
(無窮小, 10]
(10,11]
(11,13]
(13,20]
(20, 無窮大)

下面分析何種情況下會發(fā)生死鎖.
結(jié)合業(yè)務(wù)邏輯, 執(zhí)行新增操作時也會執(zhí)行一樣的邏輯, 先進(jìn)行delete.
例如,現(xiàn)在表student中有四條數(shù)據(jù):

Image 1

現(xiàn)在要新增一條數(shù)據(jù), no = 21, 這時候會先進(jìn)行delete, 線程會鎖住(20, 無窮大)這塊區(qū)間, 加入這個時候另一個線程正在新增另一條數(shù)據(jù) no = 22, 線程也會鎖住(20, 無窮大)這塊區(qū)間就會發(fā)生死鎖.

下面看具體實驗:
創(chuàng)建一張表student.

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `no` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_no` (`no`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1

插入數(shù)據(jù):

INSERT INTO student (no,name) VALUES(10, "Jim");
INSERT INTO student (no,name) VALUES(11, "Kimi");
INSERT INTO student (no,name) VALUES(13, "Tom");
INSERT INTO student (no,name) VALUES(20, "Mike");
Image 2

執(zhí)行兩個事務(wù):
session 1:

begin;
delete from student where no = 21;

session 2:

begin;
delete from student where no = 22;

此處解釋一下, 此時,session 1和session 2都會對區(qū)間(20, 無窮大)加鎖, 而區(qū)間鎖只是用來防止其他事務(wù)在區(qū)間中插入數(shù)據(jù),區(qū)間x鎖 與區(qū)間S鎖效果是一樣的(只要不是插入操作), 因此兩個session都會持有鎖.

參考:https://dev.mysql.com/doc/refman/5.1/en/innodb-record-level-locks.html
Gap locks in InnoDB are “purely inhibitive”, which means they only stop other transactions from inserting to the gap. Thus, a gap X-lock has the same effect as a gap S-lock.

繼續(xù)執(zhí)行:
session 1:

INSERT INTO student (no,name) VALUES(21, "Zhoubing");

此時session 1阻塞(因為session 2持有區(qū)間鎖), 如圖:

Image 3

session 2:

INSERT INTO student (no,name) VALUES(22, "Zhoubing");

此時session 2死鎖(因為session 1持有區(qū)間鎖), 如圖:


Image 4

.

總結(jié), delete之后進(jìn)行insert有可能發(fā)生死鎖, 因為delete可能會持有區(qū)間鎖, 而區(qū)間鎖是可重入的(只要不是插入數(shù)據(jù)).

解決方案:
將事務(wù)隔離級別將為read commit.

參考資料:
1.Next-Key Locks
2.Locks Set by Different SQL Statements in InnoDB

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欧宜,一起剝皮案震驚了整個濱河市坐榆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冗茸,老刑警劉巖席镀,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夏漱,居然都是意外死亡豪诲,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門挂绰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屎篱,“玉大人,你說我怎么就攤上這事扮授》际遥” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵刹勃,是天一觀的道長。 經(jīng)常有香客問我嚎尤,道長荔仁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮乏梁,結(jié)果婚禮上次洼,老公的妹妹穿的比我還像新娘。我一直安慰自己遇骑,他們只是感情好卖毁,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著落萎,像睡著了一般亥啦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上练链,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天翔脱,我揣著相機(jī)與錄音,去河邊找鬼媒鼓。 笑死届吁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绿鸣。 我是一名探鬼主播疚沐,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼潮模!你這毒婦竟也來了濒旦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤再登,失蹤者是張志新(化名)和其女友劉穎尔邓,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锉矢,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡梯嗽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了沽损。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灯节。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖绵估,靈堂內(nèi)的尸體忽然破棺而出炎疆,到底是詐尸還是另有隱情,我是刑警寧澤国裳,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布形入,位于F島的核電站,受9級特大地震影響缝左,放射性物質(zhì)發(fā)生泄漏亿遂。R本人自食惡果不足惜浓若,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蛇数。 院中可真熱鬧挪钓,春花似錦、人聲如沸耳舅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浦徊。三九已至馏予,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辑畦,已是汗流浹背吗蚌。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留纯出,地道東北人蚯妇。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像暂筝,于是被迫代替她去往敵國和親箩言。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

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

  • MySQL技術(shù)內(nèi)幕:InnoDB存儲引擎(第2版) 姜承堯 第1章 MySQL體系結(jié)構(gòu)和存儲引擎 >> 在上述例子...
    沉默劍士閱讀 7,417評論 0 16
  • 當(dāng)一個系統(tǒng)訪問量上來的時候焕襟,不只是數(shù)據(jù)庫性能瓶頸問題了陨收,數(shù)據(jù)庫數(shù)據(jù)安全也會浮現(xiàn),這時候合理使用數(shù)據(jù)庫鎖機(jī)制就顯得異...
    初來的雨天閱讀 3,575評論 0 22
  • 前言 數(shù)據(jù)庫鎖定機(jī)制是數(shù)據(jù)庫為了保證數(shù)據(jù)的一致性而使各種共享資源在并發(fā)訪問時變的有序的一種規(guī)則鸵赖。MySQL數(shù)據(jù)庫的...
    Justlearn閱讀 1,673評論 0 4
  • 1背景1 1.1MVCC:Snapshot Read vs Current Read2 1.2Cluster In...
    簡小鹿奔跑ing閱讀 4,162評論 1 50
  • 基本上大多數(shù)人都是以自我為中心的去闡述一個事情务漩,應(yīng)該是一個觀點。這個認(rèn)知看來也是我的個人觀點它褪。角度饵骨,認(rèn)知,邏輯思維...
    木木梵音yoga閱讀 725評論 0 4