2011-03-22 71 views
20

有时候,我得到这样的异常不是很繁忙的SQL服务器上: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 - >插入 - >触发 - > procedure02!)

回答

32

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

  1. Trap or Catch死锁错误这样就可以重新运行被选为由SQL Server数据库引擎的死锁牺牲品交易。

  2. 找出是什么原因导致您的死锁事件。 您可以通过以下两种方式之一进行,无论是运行SQL Server Profiler跟踪来捕捉和记录死锁事件,也可以使一些SQL Server Trace Flags将死锁事件的详细信息记录到SQL Server错误日志。

在案件绝大多数,您可以识别您的死锁事件的原因,并通过在数据库架构或任一个结构性变化的代码参与/逻辑变化负责的亡羊补牢死锁事件。

进一步的阅读来看看:

我希望我已经回答了你的问题,但不要让我知道如果我能帮助你进一步以任何方式。

+0

谢谢你约翰,你没有回答我的问题。我需要在我的代码中执行很多更改... – 2011-03-22 14:33:15

5

设置捕获死锁图形事件的服务器端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 [email protected] 
goto finish 

error: 
select [email protected] 

finish: 
go 
+0

在我的情况下,它缺少导致死锁的索引。 – singhswat 2017-09-06 08:49:06

+0

我如何使用UNC路径? – Drewdin 2018-03-02 15:36:19

1

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