【问题标题】:Basic select deadlocks itself基本选择死锁本身
【发布时间】:2014-10-02 21:37:28
【问题描述】:

因此,我一直在研究更多使用其中一些的 SQL 服务器管理工​​具,我惊讶地发现简单的选择会阻塞自己并导致死锁。我做了一些研究,但我真的很惊讶这会发生。谁能澄清或解决为什么会发生这种情况?

我说的是一个简单的选择。

 SELECT
     ID
 FROM   
     MainTable
 WHERE 
     Name Like 'John Smith'

如果重要,请使用 Microsoft SQL Server Managment Studios。

【问题讨论】:

  • 你怎么知道它自己死锁了?你能描述一下你实际看到的吗?
  • 这本身不会导致死锁。
  • 如果您在选择数据的同时插入数据库,您的查询可能会被选为死锁牺牲品。如果你不关心看到刚刚插入的数据,你可以在你的表名后面加上with nolock,它会做一个“脏”读,不会出现死锁。
  • @Blorgbeard 我正在使用 SQL 诊断工具,而 Phil,要么我的工具在撒谎,要么你不正确......
  • 您是否收到此语句返回的死锁受害者错误?查看您看到的表明这是死锁的信息会很有帮助,即错误消息或其他内容。

标签: sql sql-server database-deadlocks


【解决方案1】:

在 SQL 2000 中,进程有时会报告为自己阻塞,但我认为这不适用于更高版本的 SQL Server。

latch waits reported as blocking

SELECT 语句肯定有可能导致死锁,因为在选择数据时会获取共享锁,但也必须有另一个进程正在尝试更新数据。

【讨论】:

  • 实际上,共享锁(除非我们处于具有 REPEATABLE READ 隔离级别的事务中 - 或更糟 - )将只保留一小部分时间,然后突然释放,至少在单行或键上.
【解决方案2】:

并行执行计划可以显示为 SPID 本身阻塞。这基本上只是线程等待查询中的其他任务完成。死锁是另一回事,由不同的会话相互等待引起。死锁(和过多的并行性)可能是需要查询和索引调整的征兆。

如果您运行的是 SQL 2008 或更高版本,死锁信息默认由 system_helath 扩展事件跟踪捕获。下面是从环形缓冲区中提取最近死锁信息的查询。这将消除一些猜测。

SELECT
       xed.value('@timestamp', 'datetime') as Creation_Date,
       xed.query('.') AS Extend_Event
FROM
(
       SELECT CAST([target_data] AS XML) AS Target_Data
       FROM sys.dm_xe_session_targets AS xt
       INNER JOIN sys.dm_xe_sessions AS xs
       ON xs.address = xt.event_session_address
       WHERE xs.name = N'system_health'
       AND xt.target_name = N'ring_buffer'
) AS XML_Data
CROSS APPLY Target_Data.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData(xed)
ORDER BY Creation_Date DESC;

【讨论】:

    【解决方案3】:

    这个简单的选择不会自己死锁,唯一可能的原因是在您阅读时更新/删除行。 尝试启动 SQL Server Profiler 并使用:

    • 死锁
    • 死锁链
    • 死锁图

    模板中的事件。 特别是死锁图将帮助您确定哪两个进程导致了死锁,以及被选为死锁受害者的进程

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-19
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 2021-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多