溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

innodb next-key lock引發(fā)的死鎖現(xiàn)象分析

發(fā)布時間:2020-08-08 15:06:09 來源:ITPUB博客 閱讀:298 作者:花花蘑菇 欄目:MySQL數(shù)據(jù)庫
這個例子是我在網(wǎng)上看到的,我分析了很久才弄明白鎖產(chǎn)生的具體過程。

數(shù)據(jù)庫的事務(wù)隔離級別是RR。

建測試表:
CREATE TABLE `LockTest` (
   `order_id` varchar(20) NOT NULL,
   `id` bigint(20) NOT NULL AUTO_INCREMENT,
   PRIMARY KEY (`id`),
   KEY `idx_order_id` (`order_id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;

測試步驟:
事務(wù)1 事務(wù)2

begin

delete from LockTest where order_id =  'D20'

 
 

 

begin

delete from LockTest where order_id =  'D19'

insert into LockTest (order_id) values ('D20')

 
 

insert into LockTest (order_id) values ('D19')

commit

commit


測試結(jié)果:
事務(wù)1 執(zhí)行到insert語句會block住,事務(wù)2執(zhí)行insert語句會提示死鎖錯誤。

原因分析:
1、首先看測試表的建表語句,id是主鍵索引,同時該主鍵是自增主鍵。order_id是普通索引。
2、事務(wù)1執(zhí)行delete from LockTest where order_id =  'D20';語句時,由于數(shù)據(jù)庫的隔離級別是RR,因此此時事務(wù)1在主鍵id上獲得了一個next-key lock,這個鎖的范圍是[16, +∞)。
   這個16就來自于AUTO_INCREMENT=16,因為LockTest目前是張空表。
3、同理,事務(wù)2執(zhí)行delete from LockTest where order_id =  'D19';語句時,由于數(shù)據(jù)庫的隔離級別是RR,事務(wù)2在主鍵id上也獲得了一個next-key lock,這個鎖的范圍是[16, +∞)。
   也就是說此時,事務(wù)1和事務(wù)2獲得的鎖是一樣的。
4、事務(wù)1繼續(xù)執(zhí)行insert into LockTest (order_id) values ('D20');語句,這個時候由于該語句企圖往LockTest表insert一行id=16,order_id=D20的數(shù)據(jù),
   但是由于在事務(wù)2的delete語句中,主鍵id上已經(jīng)有了一個范圍為[16, +∞)的鎖,導(dǎo)致事務(wù)1此時想插入數(shù)據(jù)插不進(jìn)去,被阻塞了。

5、繼續(xù)事務(wù)2的插入語句insert into LockTest (order_id) values ('D19'); 該插入語句同樣也想LockTest表insert一行id=16,order_id=D19的數(shù)據(jù),
   
但是由于由于在事務(wù)1的delete語句中,主鍵id上已經(jīng)有了一個范圍為[16, +∞)的鎖,導(dǎo)致事務(wù)2此時想插入數(shù)據(jù)插不進(jìn)去,被阻塞了。
   此時,可以發(fā)現(xiàn),事務(wù)1和事務(wù)2的鎖是互相持有,互相等待的。所以innodb判斷該事務(wù)遇到了死鎖,直接將事務(wù)2進(jìn)行了回滾。然后回頭去看事務(wù)1,
insert into LockTest (order_id) values ('D20');被成功執(zhí)行。

如果你將數(shù)據(jù)庫的事務(wù)隔離級別修改為RC,上述事務(wù)會各自成功運(yùn)行,不會互相影響。






向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI