事务与另一个进程已被死锁在资源上,且该事务已被选作死锁牺牲品。重新运行事务

Microsoft.SQLServer.2012.Transaction_was_deadlocked_on_resources_with_another_process_and_has_been_chosen_as_the_deadlock_victim._Rerun_the_transaction_1_5_Rule (Rule)

Knowledge Base article:

摘要

当 Microsoft® SQL Server™ 遇到死锁时发生该错误。当两个(或多个)进程试图访问某个资源,而该资源上有另一个进程控制的锁时,发生死锁。因为每个进程都有对另一个资源的请求,所以各进程都不能完成。当检测到死锁时,SQL Server 将处理时间最少的命令回滚,并向客户端应用程序返回错误消息 1205。该错误不是严重错误,且不会导致批处理终止。

解决方法

在某些情况下,死锁条件将导致 DB-Library 函数(如 dbsqlexecdbsqlokdbresultsdbnextrow)返回 FAIL。程序应该始终检查从每个 DB-Library 函数返回的代码。如果这些 DB-Library 函数之一返回 FAIL,则程序应取消批处理并停止运行。在某些情况下,继续执行批处理中的后续函数是有可能的。但是,因为发生了死锁情况并且回滚了引起死锁的函数,所以批处理中的后续函数将可能因更严重的错误(如“没有找到对象”)而失败。

在其他情况下,死锁条件不会导致 DB-Library 函数返回 FAIL。在这些情况下,程序必须在消息处理程序中检查是否有错误消息 1205,并使用 dbsetuserdata 函数将此消息告知应用程序。然后程序必须在每个 DB-Library 调用之后检查是否有死锁指示符,如果检测到死锁则应取消批处理。

尽管在收到 1205 死锁消息后可能没有必要取消批处理,但因为服务器并不总是终止死锁情况下的批处理,所以这确实必要。如果未取消批处理,则任何时候试图提交新的批处理时均将导致 DB-Library 错误 10038“结果未决”。

还可以使用 SET DEADLOCK_PRIORITY 语句(LOW 或 NORMAL)。SET DEADLOCK_PRIORITY 控制在发生死锁情况时会话的反应方式。如果设置为 LOW,则进程将成为死锁情况下的首选牺牲品。如果设置为 NORMAL,则会话将使用默认的死锁处理方法。

如果死锁情况持续,则使用跟踪标记 1204 收集更多信息通常很有用。跟踪标记 1204 打印死锁链和牺牲品,如以下示例输出所示:

*** Deadlock Detected *** == Process 7 chosen as deadlock victim == Deadlock Detected at: 1998-09-10 16:39:29.17 == Session participant information: SPID: 7 ECID: 0 Statement Type: UPDATE Input Buf: update t1 set c1 = c1 where c1 = 2 SPID: 8 ECID: 0 Statement Type: UPDATE Input Buf: update t1 set c1 = c1 where c1 = 1 == Deadlock Lock participant information: == Lock: KEY: 2:117575457:1 (010001000000) Database: tempdb Table: t1 Index: i1 - Held by: SPID 7 ECID 0 Mode "S" - Requested by: SPID 8 ECID 0 Mode "X" == Lock: KEY: 2:117575457:1 (020002000000) Database: tempdb Table: t1 Index: i1 - Held by: SPID 8 ECID 0 Mode "S" - Requested by: SPID 7 ECID 0 Mode "X"

此死锁信息可以解释如下:

可替代参数

名称

说明

默认值

已启用

启用或禁用工作流。

优先级

定义警报优先级。

1

严重性

定义警报严重性。

1

Element properties:

TargetMicrosoft.SQLServer.2012.DBEngine
CategoryEventCollection
EnabledTrue
Event_ID1205
Event Source$Target/Property[Type="SQL!Microsoft.SQLServer.DBEngine"]/ServiceName$
Alert GenerateTrue
Alert SeverityWarning
Alert PriorityNormal
RemotableTrue
Alert Message
事务与另一个进程已被死锁在资源上,且该事务已被选作死锁牺牲品。重新运行事务
{0}
Event LogApplication
CommentMom2012ID='{5DEC3ED6-3871-44AB-9D4B-2433D8BAA8A5}';MOM2012GroupID={467ECC75-C5DA-42BD-955C-A73BBB51AF74}

Member Modules:

ID Module Type TypeId RunAs 
_F6DA1507_12AF_11D3_AB21_00A0C98620CE_ DataSource Microsoft.Windows.EventProvider Microsoft.SQLServer.SQLDefaultAccount
GenerateAlert WriteAction System.Health.GenerateAlert Default

Source Code:

<Rule ID="Microsoft.SQLServer.2012.Transaction_was_deadlocked_on_resources_with_another_process_and_has_been_chosen_as_the_deadlock_victim._Rerun_the_transaction_1_5_Rule" Target="SQL2012Core!Microsoft.SQLServer.2012.DBEngine" Enabled="true" ConfirmDelivery="true" Remotable="true" Comment="Mom2012ID='{5DEC3ED6-3871-44AB-9D4B-2433D8BAA8A5}';MOM2012GroupID={467ECC75-C5DA-42BD-955C-A73BBB51AF74}">
<Category>EventCollection</Category>
<DataSources>
<DataSource ID="_F6DA1507_12AF_11D3_AB21_00A0C98620CE_" Comment="{F6DA1507-12AF-11D3-AB21-00A0C98620CE}" TypeID="Windows!Microsoft.Windows.EventProvider" RunAs="SQL!Microsoft.SQLServer.SQLDefaultAccount">
<ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
<LogName>Application</LogName>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>PublisherName</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>$Target/Property[Type="SQL!Microsoft.SQLServer.DBEngine"]/ServiceName$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>1205</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</DataSource>
</DataSources>
<WriteActions>
<WriteAction ID="GenerateAlert" TypeID="SystemHealth!System.Health.GenerateAlert">
<Priority>1</Priority>
<Severity>1</Severity>
<AlertMessageId>$MPElement[Name="Microsoft.SQLServer.2012.Transaction_was_deadlocked_on_resources_with_another_process_and_has_been_chosen_as_the_deadlock_victim._Rerun_the_transaction_1_5_Rule.AlertMessage"]$</AlertMessageId>
<AlertParameters>
<AlertParameter1>Event ID: $Data/EventDisplayNumber$. $Data/EventDescription$</AlertParameter1>
</AlertParameters>
<Suppression>
<SuppressionValue/>
</Suppression>
</WriteAction>
</WriteActions>
</Rule>