Sql Server 2008中的死锁疑难解答

时间:2009-04-06 07:39:14

标签: sql-server-2008 deadlock

我的网站似乎没有处理大量访问者,我相信这是因为服务器太简单了。

2小时前我的网站获得了大量点击,我注意到发生了3次死锁错误,错误是:

  

System.Data.SqlClient.SqlException   :   事务(进程ID 58)在锁资源上与另一个进程发生死锁,并被选为死锁牺牲品。重新运行该交易。

我不确定为什么会发生这种情况......看看堆栈跟踪,我可以看到这发生在选择查询中。

任何人都知道这个错误可能是什么原因?

服务器正在运行Windows 2008和Sql Server 2008。

3 个答案:

答案 0 :(得分:11)

SQL Server 2008有多种方法可以识别死锁中涉及的进程和查询。

  1. 如果死锁很容易重现,频率更高,您可以分析SQL服务器(启用分析器时,您在服务器上具有访问和性能成本),使用SQL事件探查器将为您提供漂亮的死锁图形视图。 此页面包含使用死锁图所需的所有信息 http://sqlmag.com/database-performance-tuning/gathering-deadlock-information-deadlock-graph

  2. 大多数时候复制死锁很难,或者它们发生在我们不想将Profiler连接到它并影响性能的生产环境中。

  3. 我会使用此查询来解决发生的死锁:

    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
    

    我不会朝着使用(NOLOCK)修复死锁的方向前进。那是滑坡,隐藏了原来的问题。

答案 1 :(得分:7)

写入将阻止对SQL Server的读取,除非您启用了行版本控制。您应该使用sp_who2存储过程和SQL事件探查器跟踪。 sp_who2将告诉您哪些进程阻塞了哪些进程,并且探查器将告诉您阻塞进程的最后一个语句是什么。

答案 2 :(得分:-4)

如果你不介意脏读,你可以尝试在SELECT查询中输入(NOLOCK)表名。这里的权衡是,由于忽略了当前正在执行的UPDATE和INSERT语句,因此无法保证获得最新数据。

通常情况下,这并不是大部分系统,因为大多数系统读取的内容远远超过更新/插入,但显然这取决于应用程序的性质。

或者查看http://www.sql-server-performance.com/tips/deadlocks_p1.aspx