一、什么是死锁?
简单来说,我和你,金锁和银锁。
我拿着金锁,我需要再拿到银锁,才能完成任务,
你拿着银锁,你需要再拿到金锁,才能完成任务。
我拿不到银锁,你拿不到金锁,这就形成死锁了。
二、死锁发生后,SQL Server怎么处理?
SQL Server内置有死锁侦测和处理机制,每5S会检测一次,如果有死锁,就会评估下哪个事务回滚的开销比较低,将其kill掉,然后反馈1205错误。
实际上并没有这么简单,比如可以设置会话的优先级,优先级越低,被选为牺牲品的可能性就越大。
三、死锁发生后怎么处理?
捕获死锁>>分析死锁>>解决方案
先模拟获取死锁的demo
/*建表*/
CREATE TABLE [dbo].[deadlockTest](
[id] [int] IDENTITY(1,1) NOT NULL,
[userid] [varchar](10) NULL,
[num] [int] NULL,
CONSTRAINT [PK_deadlockTest] PRIMARY KEY CLUSTERED
(
[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]
/*建索引*/
create index ix_userid on deadlockTest(userid)
/*生成测试数据*/
insert into deadlockTest select 1,1
insert into deadlockTest select 2,2
/*事务1*/ --我
begin tran
update deadlockTest set num=100 where id=1 --金锁
update deadlockTest set num=100 where id=2 --银锁 !!注意这一句执行事务2后,回来再执行
/*事务2*/ --你
begin tran
update deadlockTest set num=100 where id=2 --银锁
update deadlockTest set num=100 where id=1 --金锁
结果:
1、捕获死锁,方法较多,常用的两种方法
>>打开跟踪标志 1222 [RDS不支持],可以从SQL SERVER日志中获取到死锁信息
DBCC TRACEON(1222,-1)
>>SQL Server Profiler抓取
2、分析死锁
完整的死锁信息【敏感信息XXX脱敏】 绿底和红字是分析文字
第一部分:牺牲品
<deadlock-list>
<deadlock victim="process40fb278">
第二部分:进程信息
<process-list>
<process id="process40fb278" taskpriority="0" logused="144" waitresource="KEY: 5:72057594039238656 (61a06abd401c)" waittime="3421" ownerId="83492" transactionname="user_transaction" lasttranstarted="2018-01-31T00:19:12.110" XDES="0xa9ac290" lockMode="X" schedulerid="4" kpid="4312" status="suspended" spid="53" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2018-01-31T00:19:17.500" lastbatchcompleted="2018-01-31T00:19:12.110" lastattention="1900-01-01T00:00:00.110" clientapp="Microsoft SQL Server Management Studio - 查询" hostname="ALI-XXX" hostpid="13556" loginname="HZ\XXX" isolationlevel="read committed (2)" xactid="83492" currentdb="5" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<executionStack>
<frame procname="adhoc" line="2" stmtstart="38" sqlhandle="0x0200000077ab791ef537624961d9a096ad0bd30107468a9100000000000000000000000000000000">
UPDATE [deadlockTest] set [num] = @1 WHERE [id]=@2 </frame>
<frame procname="adhoc" line="2" stmtstart="4" sqlhandle="0x0200000008921014831d58ffb23c0b6e1bd701b2c9540a4a00000000000000000000000000000000">
update deadlockTest set num=100 where id=2 </frame>
</executionStack>
<inputbuf>
update deadlockTest set num=100 where id=2 </inputbuf>
</process>
<process id="process40eb468" taskpriority="0" logused="144" waitresource="KEY: 5:72057594039238656 (8194443284a0)" waittime="6676" ownerId="83494" transactionname="user_transaction" lasttranstarted="2018-01-31T00:19:14.247" XDES="0x4126378" lockMode="X" schedulerid="2" kpid="4340" status="suspended" spid="52" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2018-01-31T00:19:14.247" lastbatchcompleted="2018-01-31T00:19:08.843" lastattention="1900-01-01T00:00:00.843" clientapp="Microsoft SQL Server Management Studio - 查询" hostname="ALI-XXX" hostpid="13556" loginname="HZ\XXX" isolationlevel="read committed (2)" xactid="83494" currentdb="5" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<executionStack>
<frame procname="adhoc" line="4" stmtstart="38" sqlhandle="0x0200000077ab791ef537624961d9a096ad0bd30107468a9100000000000000000000000000000000">
UPDATE [deadlockTest] set [num] = @1 WHERE [id]=@2 </frame>
<frame procname="adhoc" line="4" stmtstart="118" sqlhandle="0x02000000db1bf83585d4aab1d8142f5298a82fc3111dd0bb00000000000000000000000000000000">
update deadlockTest set num=100 where id=1
--commit </frame>
</executionStack>
<inputbuf>
begin tran
update deadlockTest set num=100 where id=2
update deadlockTest set num=100 where id=1
--commit </inputbuf>
</process>
</process-list>
第三部分:资源信息
<resource-list>
<keylock hobtid="72057594039238656" dbid="5" objectname="blockTest.dbo.deadlockTest" indexname="PK_deadlockTest" id="lock2c69480" mode="X" associatedObjectId="72057594039238656">
<owner-list>
<owner id="process40eb468" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process40fb278" mode="X" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594039238656" dbid="5" objectname="blockTest.dbo.deadlockTest" indexname="PK_deadlockTest" id="lock2c68680" mode="X" associatedObjectId="72057594039238656">
<owner-list>
<owner id="process40fb278" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process40eb468" mode="X" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>