SELECT如何阻止另一个?

时间:2010-06-08 17:59:45

标签: sql-server tsql concurrency blocking

我正在查看SQL Server 2005上SP_WhoIsActive的输出,它告诉我一个会话正在阻止另一个会话 - 很好。但是他们都运行SELECT。 SELECT如何阻止另一个?他们不应该同时获取共享锁(彼此兼容)吗?

更多细节:两个会话都没有开放的交易计数 - 因此它们是独立的。

查询使用表格加入视图。

它们是复杂的查询,它们连接了大量的表,并导致大约10,000次读取。

非常感谢任何见解。

2 个答案:

答案 0 :(得分:4)

SELECT语句可能会阻止另一个SELECT语句。你可能会认为既然两者都只获得S锁,它们就永远不会阻塞。但阻塞发生在各种类型的资源上,而不仅仅是锁。典型的例子是内存约束。我将尝试挖掘最近一个问题的答案,这个问题附加了一个向SELECT语句显示的死锁图,一个等待另一个用于并行交换运算符内存资源(缓冲区)。

<强>更新 以下是我所谈到的死锁信息的链接:I have data about deadlocks, but I can't understand why they occur 如果您研究死锁图,您会注意到等待列表中的以下资源:

<exchangeEvent id="Pipe894b0680" WaitType="e_waitPipeGetRow" nodeId="0">
  <owner-list>
    <owner id="process824df048"/>
  </owner-list>
  <waiter-list>
    <waiter id="process86ce0988"/>
  </waiter-list>
</exchangeEvent>

这不是一个锁,是一个'e_waitPipeGetRow'资源,由SELECT拥有,另一个SELECT正在等待它。有关“查询内并行资源”的一些讨论可以在这里找到:Today's Annoyingly-Unwieldy Term: "Intra-Query Parallel Thread Deadlocks"。虽然大多数讨论都将集中讨论死锁问题,但这并不意味着在这些资源上不会发生普通阻塞。 wait_type wait_resource和{{1}}将获得正确的信息。

答案 1 :(得分:0)

我认为它是因为第一个选择是执行行锁定/表锁定。在加入表格时,您可以提供无锁定提示。