SQL Server在不相交集上死锁

时间:2012-03-23 16:21:58

标签: sql-server tsql deadlock

我有以下关系

关键字(1) - ; --->(n)的K2I(n)的< --->(1)剪辑(n)的< --->(1)媒体

即,我们设置了关键字和一组剪辑。任何关键字都可以与任何剪辑相关联。可以在一个媒体上定义几个剪辑。

我有多次死锁,如下图所示:

deadlock-list
 deadlock victim=process8ba4d8
  process-list
   process id=process8ba4d8 taskpriority=0 logused=2120 waitresource=KEY: 6:72057600639696896 (37001eba95c6) waittime=7593 ownerId=2999710658 transactionname=user_transaction lasttranstarted=2012-03-23T10:13:29.140 XDES=0x2e2395e8 lockMode=U schedulerid=1 kpid=5268 status=suspended spid=295 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2012-03-23T10:13:29.857 lastbatchcompleted=2012-03-23T10:13:29.857 hostpid=2648 loginname=EVS isolationlevel=read committed (2) xactid=2999710658 currentdb=6 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=adhoc line=1 sqlhandle=0x0200000037de5708dce42f56ca1fb49fb2f34ac7f1b17d21
DELETE FROM [KeyWordsToItem] 
WHERE IdItemType = 2 AND
      IdItem IN ( 
         SELECT Id FROM [Clip]
         WHERE IdMedia = 8904 AND LSM_LouthID NOT IN ('#NCnuyFG') )     
    inputbuf
DELETE FROM [KeyWordsToItem] 
WHERE IdItemType = 2 AND
      IdItem IN ( 
         SELECT Id FROM [Clip]
         WHERE IdMedia = 8904 AND LSM_LouthID NOT IN ('#NCnuyFG') )    
   process id=processbf5018 taskpriority=0 logused=6884 waitresource=KEY: 6:72057600638255104 (810048eb4170) waittime=5000 ownerId=2999709276 transactionname=user_transaction lasttranstarted=2012-03-23T10:13:28.640 XDES=0x26f505e0 lockMode=S schedulerid=4 kpid=2488 status=suspended spid=293 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2012-03-23T10:13:29.687 lastbatchcompleted=2012-03-23T10:13:29.687 hostpid=3516 loginname=EVS isolationlevel=read committed (2) xactid=2999709276 currentdb=6 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
    executionStack
     frame procname=adhoc line=1 sqlhandle=0x020000004ccefe1488b29fbb71c97825ce7c74e9e683fd2c
DELETE FROM [KeyWordsToItem] 
WHERE IdItemType = 2 AND
      IdItem IN ( 
         SELECT Id FROM [Clip]
         WHERE IdMedia = 8905 AND LSM_LouthID NOT IN ('#NBIZhap') )     
    inputbuf
DELETE FROM [KeyWordsToItem] 
WHERE IdItemType = 2 AND
      IdItem IN (
         SELECT Id FROM [Clip]
         WHERE IdMedia = 8905 AND LSM_LouthID NOT IN ('#NBIZhap') )    
  resource-list
   keylock hobtid=72057600639696896 dbid=6 objectname=CleanEditDB.dbo.KeyWordsToItem indexname=PK_KeyWordsToItem id=lock2d9e3680 mode=U associatedObjectId=72057600639696896
    owner-list
     owner id=processbf5018 mode=U
    waiter-list
     waiter id=process8ba4d8 mode=U requestType=wait
   keylock hobtid=72057600638255104 dbid=6 objectname=CleanEditDB.dbo.Clip indexname=IX_Clip id=lock78200640 mode=X associatedObjectId=72057600638255104
    owner-list
     owner id=process8ba4d8 mode=X
    waiter-list
     waiter id=processbf5018 mode=S requestType=wait

我的理解是,2个事务对2个不相交的数据集进行操作。

那为什么会出现僵局? 这是因为服务器在场景后面占用了页面锁吗?

如何防止它们发生?

感谢您的帮助!

以下是表和索引定义:

CREATE TABLE [dbo].[KeyWordsToItem](
    [IdKeyWord] [dbo].[identifier] NOT NULL,
    [IdItem] [dbo].[identifier] NOT NULL,
    [IdItemType] [dbo].[identifier] NOT NULL,
    [PosIndex] [tinyint] NOT NULL,
 CONSTRAINT [PK_KeyWordsToItem] PRIMARY KEY CLUSTERED 
(
    [IdItemType] ASC,
    [IdItem] ASC,
    [IdKeyWord] ASC,
    [PosIndex] 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 NONCLUSTERED INDEX [IX_KeyWordsToItem_KeyWord] ON [dbo].[KeyWordsToItem] 
(
    [IdKeyWord] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

CREATE TABLE [dbo].[KeyWords](
    [Id] [dbo].[identifier] IDENTITY(1,1) NOT NULL,
    [Keyword] [nvarchar](64) NOT NULL,
 CONSTRAINT [PK_KeyWords] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Clip](
    [Id] [dbo].[identifier] IDENTITY(1,1) NOT NULL,
    [IdMedia] [dbo].[identifier] NOT NULL,
    [TcInMedia] [dbo].[fields] NOT NULL,
    [Label] [nvarchar](256) NOT NULL,
    [Duration] [dbo].[fields] NOT NULL,
 CONSTRAINT [PK_Clip] PRIMARY KEY NONCLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_Clip_IdMedia] ON [dbo].[Clip] 
(
    [IdMedia] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Media](
    [Id] [dbo].[identifier] IDENTITY(1,1) NOT NULL,
    [IdMediaFileLow] [dbo].[identifier] NULL,
    [IdMediaFileHigh] [dbo].[identifier] NULL,
    [Label] [nvarchar](256) NOT NULL,
    [LSM_LouthID] [nchar](8) NULL,
    [Version] [timestamp] NOT NULL,
 CONSTRAINT [PK_Media] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE NONCLUSTERED INDEX [IX_Media_IdMediaFileHigh] ON [dbo].[Media] 
(
    [IdMediaFileHigh] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_Media_IdMediaFileLow] ON [dbo].[Media] 
(
    [IdMediaFileLow] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
GO

2 个答案:

答案 0 :(得分:3)

由于哈希冲突,两个不相交的集仍然可能死锁,请参阅%%LOCKRES%% Collision probability magic marker: 16,777,215

然而,你的僵局并非如此。死锁涉及表CleanEditDB.dbo.Clip,它不会出现在语句中的任何位置,但是一个事务对其进行S锁定而另一个事务需要X锁定。这让我相信有一个级联删除外键,或者这里涉及的另一个类似的“带外”机制。您必须发布所涉及对象的确切定义,包括所有索引和所有外键。

答案 1 :(得分:1)

您的[Clip]表上没有Clustered Key。使主键([Id])聚集。

此外,您列出的表定义有问题。死锁图似乎认为您正在查询[Clip]表中的LSM_LouthID列,但您只在[Media]表中列出该列。

如果[Clip]中确实 这样的列,则在[clip]表列(IdMedia,LSM_LouthId)上添加非聚集索引。

我相信这些改变会让这个问题消失。