環(huán)境: sqlserver 2008
事務(wù)(進(jìn)程 ID (n))與另一個(gè)進(jìn)程被死鎖在鎖資源上,并且已被選作死鎖犧牲品。請(qǐng)重新運(yùn)行
死鎖原理:
如兩個(gè)任務(wù)
任務(wù)1,已經(jīng)鎖定R1,再進(jìn)行請(qǐng)求R2<R2此時(shí)被任務(wù)2鎖定>
任務(wù)2,已經(jīng)鎖定R2,再進(jìn)行請(qǐng)求R1<R1此時(shí)被任務(wù)1鎖定>
導(dǎo)致兩個(gè)任務(wù)都進(jìn)入了阻塞。SQLSERVER會(huì)選擇一個(gè)進(jìn)行犧牲。
了解了原理后,來(lái)段SQL
-- 表結(jié)構(gòu)和模擬數(shù)據(jù)CREATETABLE R1(
? ? ID INTNOTNULL,
? ? Name varchar(50)NULL,
? ? Num INTNULLCONSTRAINT[PK_R1]PRIMARYKEYCLUSTERED
(
? ? [ID]ASC)
? ? WITH(PAD_INDEX=OFF, STATISTICS_NORECOMPUTE=OFF,
? ? IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS=ON,
? ? ALLOW_PAGE_LOCKS =ON)
? ? ON[PRIMARY]) ON[PRIMARY]GOINSERTINTOR1(ID, Name, Num)VALUES(1,'張三',50)INSERTINTOR1(ID, Name, Num)VALUES(2,'李四',50)CREATETABLE R2(
? ? ID INTNOTNULL,
? ? Name varchar(50)NULL,
? ? Num INTNULLCONSTRAINT[PK_R2]PRIMARYKEYCLUSTERED
(
? ? [ID]ASC)
? ? WITH(PAD_INDEX=OFF, STATISTICS_NORECOMPUTE=OFF,
? ? IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS=ON,
? ? ALLOW_PAGE_LOCKS =ON)
? ? ON[PRIMARY]) ON[PRIMARY]GOINSERTINTOR2(ID, Name, Num)VALUES(1,'張三',50)INSERTINTOR2(ID, Name, Num)VALUES(2,'李四',50)
任務(wù)1:
begin tran t1
-- R1
update [dbtest].[dbo].[R1] SET Num = 91 WHERE Name = '張三'
-- R2
update [dbtest].[dbo].[R2] SET Num = 91 WHERE Name = '李四'
rollback tran t1
任務(wù)2:
begin tran t2
-- R2
update [dbtest].[dbo].[R2] SET Num = 91 WHERE Name = '李四'
-- R1
update [dbtest].[dbo].[R1] SET Num = 91 WHERE Name = '張三'
rollback tran t2
執(zhí)行方法:
1.在任務(wù)1里面執(zhí)行前兩句(開(kāi)啟事務(wù), 鎖定R1)
2.然后切換到任務(wù)2里面執(zhí)行前兩句(開(kāi)啟事務(wù), 鎖定R2)
3.在任務(wù)1里面執(zhí)行鎖定R2(update R2…)此時(shí)要請(qǐng)求的R2被任務(wù)2鎖定
4.在任務(wù)2里面執(zhí)行鎖定R1(Update R1…)此時(shí)請(qǐng)求的R1被任務(wù)1鎖定。
進(jìn)入了死鎖,然后會(huì)彈出死鎖的信息。
消息 1205,級(jí)別 13,狀態(tài) 51,第 2 行?
事務(wù)(進(jìn)程 ID 89)與另一個(gè)進(jìn)程被死鎖在 鎖 資源上,并且已被選作死鎖犧牲品。請(qǐng)重新運(yùn)行該事務(wù)。