共享锁可以等待共享锁完成吗?

时间:2013-12-08 08:34:11

标签: sql sql-server-2012

我的服务器上遇到了一些死锁异常。我能够获取一些扩展事件日志,

<resource-list>
    <pagelock fileid="1" pageid="89158" dbid="5" subresource="FULL" objectname="DB.dbo.Products" id="lock2fba9b780" mode="SIX" associatedObjectId="72057594050445312">
      <owner-list>
        <owner id="process2f64a3868" mode="S" requestType="wait" />
      </owner-list>
      <waiter-list>
        <waiter id="process2f6986cf8" mode="S" requestType="wait" />
      </waiter-list>
    </pagelock>
    <pagelock fileid="1" pageid="89158" dbid="5" subresource="FULL" objectname="DB.dbo.Products" id="lock2fba9b780" mode="SIX" associatedObjectId="72057594050445312">
      <owner-list>
        <owner id="process2f64a3868" mode="S" requestType="wait" />
      </owner-list>
      <waiter-list>
        <waiter id="process2f6987c38" mode="S" requestType="wait" />
      </waiter-list>
    </pagelock>
    <pagelock fileid="1" pageid="89158" dbid="5" subresource="FULL" objectname="DB.dbo.Products" id="lock2fba9b780" mode="SIX" associatedObjectId="72057594050445312">
      <owner-list>
        <owner id="process2f6c9e928" mode="SIX" />
      </owner-list>
      <waiter-list>
        <waiter id="process2f64a3868" mode="S" requestType="wait" />
      </waiter-list>
    </pagelock>
    <pagelock fileid="1" pageid="86733" dbid="5" subresource="FULL" objectname="DB.dbo.Products" id="lock2f200fa80" mode="SIU" associatedObjectId="72057594050445312">
      <owner-list>
        <owner id="process2f6987c38" mode="S" />
        <owner id="process2f6986cf8" mode="S" />
      </owner-list>
      <waiter-list>
        <waiter id="process2f6c9e928" mode="IX" requestType="convert" />
      </waiter-list>
    </pagelock>
  </resource-list>

看到日志似乎是共享锁正在等待共享锁完成。

1 个答案:

答案 0 :(得分:2)

如下图所示:

enter image description here

生成此死锁的进程/会话为process2f6c9e928

1)此过程在页面5:1:89158(DB:FILEID:PAGENUM)上有一个SIX锁定,并且需要/等待页面5:1:86733上的IX锁定(DB:FILEID:PAGENUM)。但页面5:1:86733已被process2f6986cf8&amp; process2f6987c38因为他们有S锁。 SIX(现有)和S(请求)锁是不兼容的(参见下面的兼容性矩阵)。

2)以下过程:process2f6986cf8&amp; process2f6987c38在页面5:1:86733上有S锁,他们等待5:1:89158上的S锁定。但页面5:1:89158已被process2f6c9e928锁定。此过程在此页面上有一个SIX锁定。 S(现有)和IX(请求)锁是不兼容的(参见下面的兼容性矩阵)。

由于这些不兼容的锁(SIX vs S,S vs. IX),你会遇到这种僵局。

S,SIX和IX锁的兼容性矩阵:(见Lock compatibility

                Existing granted mode
Requested mode  S        SIX    IX
S               [Yes]    [No]   No
SIX             No       No     No
IX              [No]     No     Yes

现在,你的问题

  

共享锁可以等待共享锁完成吗?

指的是(我认为)死锁图事件的这一部分:

  <owner-list>
    <owner id="process2f64a3868" mode="S" requestType="wait" />
  </owner-list>
  <waiter-list>
    <waiter id="process2f6986cf8" mode="S" requestType="wait" />
  </waiter-list>

观点:即使一个进程是“owner”,第二个进程是服务员,我认为两个进程都在等待(requestType="wait")。因此,S锁之间没有不兼容性。从兼容性矩阵可以看出S锁与另一个S锁兼容。

观点:您应该首先关注为什么某些进程(68,f8,38)尝试使用S锁定整个页面来锁定。也许,你使用REPEATABLE READ隔离级别,导致页面上S锁的执行计划有{Table | [Clustered] Index}扫描操作符?