3

アプリケーションでデッドロックが発生するという問題があります。DB は SQL サーバー 2005 であり、2 つのスレッドが同じテーブルを更新しようとするとデッドロックが発生します。私は状況を理解していません。誰かが私を助けてくれることを願っています。デッドロック グラフは次のとおりです。

<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 つのスレッドによって渡された値がログに記録されていないとは言えません :(

4

1 に答える 1

4

このデッドロックに関係する行を特定するには、クエリを実行します。

SELECT id, %%lockres%% を LockResource として dbo.FreeAvailability WHERE %%lockres%% IN('(e100ae2e5d7f)','(d0006ab1ca37)')

このデッドロックでは、プロセス process3a0ac58 は、リソース (e100ae2e5d7f) に対応する行で X ロックを保持し、リソース (d0006ab1ca37) に対応する行で U ロック (UPDATE の読み取りフェーズ用) を待機しています。

一方、プロセス process3a28da8 は、リソース (d0006ab1ca37) に対応する行で X ロックを保持し、U ロック (e100ae2e5d7f) を待機しています。

デッドロック トレースでは、ロックを取得したステートメントはわかりません。私の推測では、同じトランザクションで複数の UPDATE を実行していると思います。この場合も、UPDATE は逆の順序で実行されます。

(PK の WHERE 句による) キー レベル ロックを使用する 2 つの独立した UPDATE ステートメントは、互いにデッドロックしません。したがって、これは古典的な循環デッドロックのケースであるはずです。

于 2012-07-21T00:21:00.047 に答える