2012-07-20 134 views
3

我遇到了在我的應用程序中發生死鎖的問題。 數據庫是SQL Server 2005,當2個線程嘗試更新同一個表時發生死鎖。 我不瞭解情況,我希望有人能幫助我。 這裏是死鎖圖形:UPDATE上的SQL Server死鎖

<deadlock-list> 
    <deadlock victim="process3a0ac58"> 
     <process-list> 
     <process id="process3a0ac58" taskpriority="0" logused="5048" waitresource="KEY: 9:72057594078035968 (e100ae2e5d7f)" waittime="4750" ownerId="22329947" transactionname="user_transaction" lasttranstarted="2012-07-20T08:53:33.440" XDES="0x24b429210" lockMode="U" schedulerid="1" kpid="1428" status="suspended" spid="57" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2012-07-20T08:53:34.753" lastbatchcompleted="2012-07-20T08:53:34.753" clientapp=".Net SqlClient Data Provider" hostname="VMDBSRVCRISPI" hostpid="4012" loginname="sa" isolationlevel="read uncommitted (1)" xactid="22329947" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> 
      <executionStack> 
       <frame procname="adhoc" line="1" stmtstart="34" sqlhandle="0x0200000008adf4202a2e77131e147fe8c50b173a5f8d5302"> UPDATE [FreeAvailability] SET Resource_id = null WHERE Resource_id = @p0 AND Id = @p1 </frame> 
       <frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000"> unknown </frame> 
      </executionStack> 
      <inputbuf> (@p0 int,@p1 int)UPDATE [FreeAvailability] SET Resource_id = null WHERE Resource_id = @p0 AND Id = @p1 </inputbuf> 
     </process> 
     <process id="process3a28da8" taskpriority="0" logused="8720" waitresource="KEY: 9:72057594078035968 (d0006ab1ca37)" waittime="2734" ownerId="22329913" transactionname="user_transaction" lasttranstarted="2012-07-20T08:53:33.067" XDES="0x28dd4aa40" lockMode="U" schedulerid="4" kpid="3732" status="suspended" spid="58" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2012-07-20T08:53:36.770" lastbatchcompleted="2012-07-20T08:53:36.737" clientapp=".Net SqlClient Data Provider" hostname="VMDBSRVCRISPI" hostpid="4012" loginname="sa" isolationlevel="read uncommitted (1)" xactid="22329913" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> 
      <executionStack> 
       <frame procname="adhoc" line="1" stmtstart="34" sqlhandle="0x0200000008adf4202a2e77131e147fe8c50b173a5f8d5302"> UPDATE [FreeAvailability] SET Resource_id = null WHERE Resource_id = @p0 AND Id = @p1 </frame> 
       <frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000"> unknown </frame> 
      </executionStack> 
      <inputbuf> (@p0 int,@p1 int)UPDATE [FreeAvailability] SET Resource_id = null WHERE Resource_id = @p0 AND Id = @p1 </inputbuf> 
     </process> 
     </process-list> 
     <resource-list> 
     <keylock hobtid="72057594078035968" dbid="9" objectname="SDN.Napoli.dbo.FreeAvailability" indexname="PK__FreeAvailability__3939548A" id="lock4bdb180" mode="X" associatedObjectId="72057594078035968"> 
      <owner-list> 
       <owner id="process3a28da8" mode="X"/> 
      </owner-list> 
      <waiter-list> 
       <waiter id="process3a0ac58" mode="U" requestType="wait"/> 
      </waiter-list> 
     </keylock> 
     <keylock hobtid="72057594078035968" dbid="9" objectname="SDN.Napoli.dbo.FreeAvailability" indexname="PK__FreeAvailability__3939548A" id="lock4c25680" mode="X" associatedObjectId="72057594078035968"> 
      <owner-list> 
       <owner id="process3a0ac58" mode="X"/> 
      </owner-list> 
      <waiter-list> 
       <waiter id="process3a28da8" mode="U" requestType="wait"/> 
      </waiter-list> 
     </keylock> 
     </resource-list> 
    </deadlock> 
</deadlock-list> 

似乎死鎖發生在主鍵,但它是如何可能的,我怎麼能解決這個問題呢?

在此先感謝

編輯:

這是表結構:

CREATE TABLE [dbo].[FreeAvailability](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [Date] [datetime] NULL, 
    [StartTime] [datetime] NULL, 
    [EndTime] [datetime] NULL, 
    [BookOnlyIfRequired] [bit] NULL, 
    [Free48HsBefore] [bit] NULL, 
    [Private] [bit] NULL, 
    [F48HBGroup] [bit] NULL, 
    [Resource_id] [int] NULL, 
    [Sedi_id] [int] NULL, 
    [Skill_id] [int] NULL, 
    [BOIRGroup_id] [int] NULL, 
    [Private48HBGroup] [bit] NULL, 
    [Free24HsBefore] [bit] NULL, 
    [Free72HsBefore] [bit] NULL, 
    [F24HBGroup] [bit] NULL, 
    [F72HBGroup] [bit] NULL, 
    [Private24HBGroup] [bit] NULL, 
    [Private72HBGroup] [bit] NULL, 
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] 

GO 
ALTER TABLE [dbo].[FreeAvailability] WITH CHECK ADD CONSTRAINT [FK4D396931200F9F6C] FOREIGN KEY([Skill_id]) 
REFERENCES [dbo].[Skill] ([Id]) 
GO 
ALTER TABLE [dbo].[FreeAvailability] CHECK CONSTRAINT [FK4D396931200F9F6C] 
GO 
ALTER TABLE [dbo].[FreeAvailability] WITH CHECK ADD CONSTRAINT [FK4D3969313F693A26] FOREIGN KEY([BOIRGroup_id]) 
REFERENCES [dbo].[BOIRGroup] ([Id]) 
GO 
ALTER TABLE [dbo].[FreeAvailability] CHECK CONSTRAINT [FK4D3969313F693A26] 
GO 
ALTER TABLE [dbo].[FreeAvailability] WITH CHECK ADD CONSTRAINT [FK4D396931C92BB494] FOREIGN KEY([Resource_id]) 
REFERENCES [dbo].[Resource] ([Id]) 
GO 
ALTER TABLE [dbo].[FreeAvailability] CHECK CONSTRAINT [FK4D396931C92BB494] 
GO 
ALTER TABLE [dbo].[FreeAvailability] WITH CHECK ADD CONSTRAINT [FK556546F95E61B626] FOREIGN KEY([BOIRGroup_id]) 
REFERENCES [dbo].[BOIRGroup] ([Id]) 
GO 
ALTER TABLE [dbo].[FreeAvailability] CHECK CONSTRAINT [FK556546F95E61B626] 
GO 
ALTER TABLE [dbo].[FreeAvailability] WITH CHECK ADD CONSTRAINT [FK556546F95ECA95DC] FOREIGN KEY([Skill_id]) 
REFERENCES [dbo].[Skill] ([Id]) 
GO 
ALTER TABLE [dbo].[FreeAvailability] CHECK CONSTRAINT [FK556546F95ECA95DC] 
GO 
ALTER TABLE [dbo].[FreeAvailability] WITH CHECK ADD CONSTRAINT [FK556546F9E6E3AAC4] FOREIGN KEY([Resource_id]) 
REFERENCES [dbo].[Resource] ([Id]) 
GO 
ALTER TABLE [dbo].[FreeAvailability] CHECK CONSTRAINT [FK556546F9E6E3AAC4] 

我不能說通過2線傳遞,因爲我不日誌值:(

+0

請向我們展示您的表格結構!你有什麼列(及其數據類型)?你在桌上有什麼樣的索引?你的兩個線程正在更新什麼'Resource_Id'和'ID'的值? – 2012-07-20 13:06:36

+0

這將是一個很好的起點 http://sqlindian.com/2012/07/06/sql-server-deadlocks-and-live-lockscommon-patterns/ – Madhivanan 2012-07-20 13:13:45

+2

這些更新是另一個交易的一部分?在啓動更新之前,在同一個表上的某些行上會鎖定某種類型的鎖?此外,表上還有什麼樣的非聚簇索引? – 2012-07-20 15:01:14

回答

4

要確定涉及此死鎖的行,請運行查詢

SELECT ID,%% lockres %%作爲LockResource FROM dbo.FreeAvailability WHERE %% lockres %% IN( '(e100ae2e5d7f)', '(d0006ab1ca37)')

在這種僵局,過程process3a0ac58被保持的X鎖定與資源(e100ae2e5d7f)相對應的行並等待資源(d0006ab1ca37)對應的行上的U鎖(用於UPDATE的讀取階段)。

同時process3a28da8在與資源(d0006ab1ca37)對應的行上持有X鎖並等待U鎖(e100ae2e5d7f)。

死鎖跟蹤不會告訴你什麼語句獲得鎖。我的猜測是你在同一個事務中執行多個UPDATE。同樣在這種情況下,UPDATE以相反的順序執行。

使用鍵級鎖的兩個獨立的UPDATE語句(由於PK上的WHERE子句)不會相互死鎖。所以這應該是經典循環死鎖的情況,如here所解釋的。