最近我在客户端的OLTP框(Sql server 2005)上遇到了死锁情况,发现它是由两个不同线程调用的两个存储过程引起的.
1,插入在X表中插入数据的sp.
Insert Into X (col1 , col2 , col3 )
Values ('value 1' , 'value 2' , 'value 3' )
Run Code Online (Sandbox Code Playgroud)
2,删除从X表中删除数据的sp.
DELETE X
FROM X T1 WITH (NOLOCK)
INNER JOIN Y T2 WITH (NOLOCK)
ON T1.[col2] = T2.[col2]
WHERE t2.date < 'date time value'
Run Code Online (Sandbox Code Playgroud)
X表有一个唯一的聚簇主键和两个非聚簇的非唯一索引.我通过设置t1222 tace标志来分析死锁,输出总结如下;
插入sp在第1列的非聚集索引上获取了IX锁定.在此期间,删除sp正在等待第1列的同一非聚集索引上的X锁定.
删除sp在第2列的非聚集索引上获取U锁定.在此期间,插入sp正在等待第2列的同一非聚集索引上的IX锁定.
任何想要或建议避免死锁都会非常感激.
编辑
跟踪标志t1222的输出
deadlock-list
deadlock victim=process3c77d68
process-list
process id=process3c12c58 taskpriority=0 logused=1044 waitresource=PAGE: 17:8:7726 waittime=1250 ownerId=5169682909 transactionname=user_transaction lasttranstarted=2011-02-03T03:34:03.443 XDES=0xfe64d78b0 lockMode=IX schedulerid=2 kpid=9544 status=suspended spid=219 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2011-02-03T03:34:03.457 lastbatchcompleted=2011-02-03T03:34:03.453 …Run Code Online (Sandbox Code Playgroud)