有puber在SQLServer版發了一個帖子SQL server2005+Sp3的死鎖問題,因最近正在研究SQLServer的一些問題,出於興趣決定試試看能不能幫助這位pubber。
問題描述:
我的程序為多線程,同時最多20個線程。
20個線程同時向一個表中做insert操作,但是各線程之間的記錄不可能重復(主鍵肯定不一樣),但是還是報死鎖,同樣的程序連oracle運行時卻很正常。
各高人給指出個明路啊。
問題分析:
因為只有這些簡單的介紹,很難去定位和診斷問題所在,所以我一開始建議啟用他1204和1222跟蹤標志,通過日志把死鎖描述信息詳細列出來;或者用SQL Server Profiler的定制事件跟蹤。
他回復SQL Server Profiler的定制事件跟蹤Deadlock graph得到一個關於健鎖的描述
以下為死鎖圖:
以下為SQLServer日志信息:
下面是日志查看器中的信息,應該對應 已用日志1160 和已用日志1084 吧。
----------------------------------------------------------------------------
日期 2011-1-14 11:15:11
日志 SQL Server (當前 - 2011-1-14 11:15:00)
源 spid21s
消息
process id=processb793d8 taskpriority=0 logused=1084 waitresource=KEY: 9:72057594058113024 (c601cdd76f20) waittime=4984 ownerId=944254 transactionname=INSERT lasttranstarted=2011-01-14T11:15:06.500 XDES=0x8ee8a88 lockMode=S schedulerid=2 kpid=7384 status=suspended spid=69 sbid=0 ecid=0 priority=0 transcount=1 lastbatchstarted=2011-01-14T11:15:06.500 lastbatchcompleted=2011-01-14T11:15:06.497 clientapp=jTDS hostname=WIN7-PC hostpid=123 loginname=ipcc isolationlevel=read committed (2) xactid=944254 currentdb=9 lockTimeout=4294967295 clientoption1=671219744 clientoption2=128056
-----------------------------------------------------------------------------------
日期 2011-1-14 11:15:11
日志 SQL Server (當前 - 2011-1-14 11:15:00)
源 spid21s
消息
process id=processaea988 taskpriority=0 logused=1160 waitresource=KEY: 9:72057594058113024 (3002597d4e10) waittime=4984 ownerId=944255 transactionname=INSERT lasttranstarted=2011-01-14T11:15:06.500 XDES=0x7e3ea88 lockMode=S schedulerid=1 kpid=4208 status=suspended spid=79 sbid=0 ecid=0 priority=0 transcount=1 lastbatchstarted=2011-01-14T11:15:06.500 lastbatchcompleted=2011-01-14T11:15:06.497 clientapp=jTDS hostname=WIN7-PC hostpid=123 loginname=ipcc isolationlevel=read committed (2) xactid=944255 currentdb=9 lockTimeout=4294967295 clientoption1=671219744 clientoption2=128056
初步分析了一下以上日志和圖形:
表面提示是一個共享鎖和排他鎖相互沖突了,即讀寫和寫讀沖突
session1 session2
共享鎖
排它鎖
排它鎖
共享鎖
經過詢問和分析,的確是發生在主鍵上,我懷疑是觸發器問題,觸發器中執行時間過長, 或者在程序中進行主鍵生成的過程中,又重復從該表中進行讀取。所以想進一步了解表結構、觸發器腳本和主鍵生成的腳本。
問題解決:
經過幾輪折騰,終於他找到了問題所在,“原來是其他人在這個表中建立了觸發器,我不知道,並且這個觸發器還訪問了這個表。”,去掉觸發器,問題消失。
死鎖常見的場景是讀寫寫讀沖突,循環引用會造成相互資源的排斥,同時資源得不到釋放,建議解決方式,是縮短事務處理時間,減少循環引用等等方法。