【问题标题】:SQL Transaction was deadlockedSQL 事务已死锁
【发布时间】:2011-03-22 09:41:31
【问题描述】:

有时我会在不太繁忙的 SQL 服务器上遇到这种异常:

Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Line number: 1
Error Number: 1205
Procedure: 
Server name: P01
Error Source: .Net SqlClient Data Provider
Error State: 47

我无法重现它。我尝试同时从不同的客户端运行多个查询,但没有出现。 当这种问题发生在程序内部或触发器内部时,处理此类问题的最佳方法是什么?我的意思是,如何重新运行事务?

当触发器调用的过程内部发生异常时如何处理,该过程是由某个过程(即:procedure01 -> insert -> trigger -> procedure02!)进行的插入调用的。

【问题讨论】:

    标签: sql-server exception stored-procedures triggers


    【解决方案1】:

    我建议你从两个角度来解决这个问题。

    1. Trap or Catch 死锁错误,以便您可以重新运行被 SQL Server 数据库引擎选择为死锁受害者的事务。 p>

    2. 找出导致您的死锁事件的原因。 您可以通过以下两种方式之一执行此操作,或者运行 SQL Server Profiler Trace 来捕获和记录死锁事件,或者您可以启用一些 SQL Server Trace Flags,它将死锁事件的详细信息记录到SQL Server 错误日志。

    绝大多数案例中,您可以确定死锁事件的原因并通过数据库架构中的结构更改或对所涉及/负责的代码的逻辑更改来纠正这种情况死锁事件。

    如需进一步阅读,请查看:

    我希望我已经回答了你的问题,但如果我能以任何方式进一步帮助你,请告诉我。

    【讨论】:

    • 是什么导致您的死锁事件?而不是性能下降
    • 如果对通常导致错误的原因有任何提示,此答案会更有帮助。它在我的应用程序代码中吗? SQL过程? MSSQL 中的错误?
    【解决方案2】:

    设置服务器端 SQL 跟踪以捕获死锁图形事件,以便您可以使用 SQL Profiler 查看 .trc 文件。这样,您就可以准备好解决任何死锁的问题。我提供了下面的代码。您必须根据需要更改文件路径。最好将此脚本配置为在 SQL Server 启动时执行。

    仅供参考 - 许多不同的事情都可能导致死锁,其中之一是缺少索引。

    declare @rc int
    declare @TraceID int
    declare @maxfilesize bigint
    set @maxfilesize = 10 
    declare @dtName nvarchar(50)
    select @dtName=(N'I:\Trace_Logs\DeadLockTrace'+ convert(nvarchar(8),getdate(),112))
    
    
    -- Please replace the text InsertFileNameHere, with an appropriate
    -- filename prefixed by a path, e.g., c:\MyFolder\MyTrace. The .trc extension
    -- will be appended to the filename automatically. If you are writing from
    -- remote server to local drive, please use UNC path and make sure server has
    -- write access to your network share
    
    exec @rc = sp_trace_create @TraceID output, 2, @dtName, @maxfilesize, NULL ,365
    
    if (@rc != 0) goto error
    
    -- Client side File and Table cannot be scripted
    
    -- Set the events
    declare @on bit
    set @on = 1
    exec sp_trace_setevent @TraceID, 148, 11, @on
    exec sp_trace_setevent @TraceID, 148, 51, @on
    exec sp_trace_setevent @TraceID, 148, 4, @on
    exec sp_trace_setevent @TraceID, 148, 12, @on
    exec sp_trace_setevent @TraceID, 148, 14, @on
    exec sp_trace_setevent @TraceID, 148, 26, @on
    exec sp_trace_setevent @TraceID, 148, 60, @on
    exec sp_trace_setevent @TraceID, 148, 64, @on
    exec sp_trace_setevent @TraceID, 148, 1, @on
    exec sp_trace_setevent @TraceID, 148, 41, @on
    exec sp_trace_setevent @TraceID, 25, 7, @on
    exec sp_trace_setevent @TraceID, 25, 15, @on
    exec sp_trace_setevent @TraceID, 25, 55, @on
    exec sp_trace_setevent @TraceID, 25, 8, @on
    exec sp_trace_setevent @TraceID, 25, 32, @on
    exec sp_trace_setevent @TraceID, 25, 56, @on
    exec sp_trace_setevent @TraceID, 25, 64, @on
    exec sp_trace_setevent @TraceID, 25, 1, @on
    exec sp_trace_setevent @TraceID, 25, 9, @on
    exec sp_trace_setevent @TraceID, 25, 25, @on
    exec sp_trace_setevent @TraceID, 25, 41, @on
    exec sp_trace_setevent @TraceID, 25, 49, @on
    exec sp_trace_setevent @TraceID, 25, 57, @on
    exec sp_trace_setevent @TraceID, 25, 2, @on
    exec sp_trace_setevent @TraceID, 25, 10, @on
    exec sp_trace_setevent @TraceID, 25, 26, @on
    exec sp_trace_setevent @TraceID, 25, 58, @on
    exec sp_trace_setevent @TraceID, 25, 3, @on
    exec sp_trace_setevent @TraceID, 25, 11, @on
    exec sp_trace_setevent @TraceID, 25, 35, @on
    exec sp_trace_setevent @TraceID, 25, 51, @on
    exec sp_trace_setevent @TraceID, 25, 4, @on
    exec sp_trace_setevent @TraceID, 25, 12, @on
    exec sp_trace_setevent @TraceID, 25, 52, @on
    exec sp_trace_setevent @TraceID, 25, 60, @on
    exec sp_trace_setevent @TraceID, 25, 13, @on
    exec sp_trace_setevent @TraceID, 25, 6, @on
    exec sp_trace_setevent @TraceID, 25, 14, @on
    exec sp_trace_setevent @TraceID, 25, 22, @on
    exec sp_trace_setevent @TraceID, 59, 55, @on
    exec sp_trace_setevent @TraceID, 59, 32, @on
    exec sp_trace_setevent @TraceID, 59, 56, @on
    exec sp_trace_setevent @TraceID, 59, 64, @on
    exec sp_trace_setevent @TraceID, 59, 1, @on
    exec sp_trace_setevent @TraceID, 59, 21, @on
    exec sp_trace_setevent @TraceID, 59, 25, @on
    exec sp_trace_setevent @TraceID, 59, 41, @on
    exec sp_trace_setevent @TraceID, 59, 49, @on
    exec sp_trace_setevent @TraceID, 59, 57, @on
    exec sp_trace_setevent @TraceID, 59, 2, @on
    exec sp_trace_setevent @TraceID, 59, 14, @on
    exec sp_trace_setevent @TraceID, 59, 22, @on
    exec sp_trace_setevent @TraceID, 59, 26, @on
    exec sp_trace_setevent @TraceID, 59, 58, @on
    exec sp_trace_setevent @TraceID, 59, 3, @on
    exec sp_trace_setevent @TraceID, 59, 35, @on
    exec sp_trace_setevent @TraceID, 59, 51, @on
    exec sp_trace_setevent @TraceID, 59, 4, @on
    exec sp_trace_setevent @TraceID, 59, 12, @on
    exec sp_trace_setevent @TraceID, 59, 52, @on
    exec sp_trace_setevent @TraceID, 59, 60, @on
    
    -- Set the Filters
    declare @intfilter int
    declare @bigintfilter bigint
    
    -- Set the trace status to start
    exec sp_trace_setstatus @TraceID, 1
    
    -- display trace id for future references
    select TraceID=@TraceID
    goto finish
    
    error: 
    select ErrorCode=@rc
    
    finish: 
    go
    

    【讨论】:

    • 在我的情况下,它缺少导致死锁的索引。
    • 如何使用 UNC 路径?
    【解决方案3】:

    我使用 ReadCommited 隔离级别解决了类似的问题。

    【讨论】:

      【解决方案4】:

      我通过以下方式解决了这个错误:

      1. 重启 SQL Server
      2. 运行查询:

        使用 [主] ALTER DATABASE name_database 设置多用户 立即回滚

      祝你好运!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多