SQL事务已陷入僵局

时间:2011-03-22 09:41:31

标签: sql-server exception stored-procedures triggers

有时我会在非常繁忙的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!)

4 个答案:

答案 0 :(得分:39)

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

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

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

  3. 绝大多数案例中,您可以确定死锁事件的原因并通过数据库架构中的结构更改或对所涉及的代码的逻辑更改来解决问题。死锁事件。

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

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

答案 1 :(得分:5)

设置服务器端SQL跟踪,捕获死锁图事件,以便您可以使用SQL事件探查器查看.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

答案 2 :(得分:2)

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

答案 3 :(得分:0)

我通过以下方法解决了此错误:

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

    USE [master] ALTER DATABASE名称_数据库 SET MULTI_USER 立即回滚

祝你好运!

相关问题