SQL Server Pagelock死锁 - INSERT和DELETE

时间:2016-02-15 22:01:36

标签: sql-server deadlock

我的客户在这两个陈述之间经常出现僵局:

DELETE b
FROM employees a WITH (NOLOCK), employees_prs b WITH (NOLOCK)
WHERE a.employer_id = @id
    AND a.id = b.employee_id
    AND b.employee_prs = 1

INSERT INTO employees_prs (employee_id, employee_prs)
SELECT DISTINCT a.id, 1
FROM #tempdata01 b, employees a WITH (NOLOCK)
WHERE a.employer_id = @id
    AND a.no_id = b.no_id

死锁图中的资源列表显示:

<resource-list>
   <pagelock fileid="4" pageid="28897262" dbid="14" objectname="db01.dbo.employees_prs" id="lock373f60880" mode="IX" associatedObjectId="72057601182466048">
    <owner-list>
     <owner id="process352a02988_INSERT" mode="IX" />
    </owner-list>
    <waiter-list>
     <waiter id="process11e0a1b88_DELETE" mode="U" requestType="wait" />
    </waiter-list>
   </pagelock>
   <pagelock fileid="4" pageid="25066463" dbid="14" objectname="db01.dbo.employees_prs" id="lock61081f580" mode="U" associatedObjectId="72057601182466048">
    <owner-list>
     <owner id="process11e0a1b88_DELETE" mode="U" />
    </owner-list>
    <waiter-list>
     <waiter id="process352a02988_INSERT" mode="IX" requestType="wait" />
    </waiter-list>
   </pagelock>
  </resource-list>

我认为DELETE语句在页面上有U锁,但也在等待另一页上的另一个U锁。同样,INSERT语句在页面上有一个IX锁,并且一直等待在另一个页面上获取另一个IX锁。 这是正确的吗?

如何解决僵局?

表格结构:

CREATE TABLE [dbo].[employees](
    [id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
    [employer] [int] NOT NULL,
    [name] [varchar](30) NULL,
 CONSTRAINT [employees_PK] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)
)


CREATE TABLE [dbo].[employees_prs](
    [employee_id] [int] NOT NULL,
    [employee_prs] [tinyint] NOT NULL,
 CONSTRAINT [PK_employees_prs] PRIMARY KEY CLUSTERED 
(
    [employee_id] ASC,
    [employee_prs] ASC
)
)

1 个答案:

答案 0 :(得分:-1)

按照语句的顺序一次一个地获取锁定,直到足够的锁定使表格安全更改为止。我不确定,但看起来您应该能够在delete语句中交换表,以便插入和删除都通过锁定employees_prs开始。第一个这样做将阻止另一个继续锁定获取直到它完成。