当 Microsoft® SQL Server™ 遇到死锁时发生该错误。当两个(或多个)进程试图访问某个资源,而该资源上有另一个进程控制的锁时,发生死锁。因为每个进程都有对另一个资源的请求,所以各进程都不能完成。当检测到死锁时,SQL Server 将处理时间最少的命令回滚,并向客户端应用程序返回错误消息 1205。该错误不是严重错误,且不会导致批处理终止。
在某些情况下,死锁条件将导致 DB-Library 函数(如 dbsqlexec、dbsqlok、dbresults 或 dbnextrow)返回 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"
此死锁信息可以解释如下:
第一部分显示死锁牺牲品、死锁时间以及死锁中涉及的会话。对于每个会话,显示当前的 SPID、语句类型和输入缓冲区的一部分。
第二部分显示有关死锁中涉及的锁的详细信息。对于上面的输出,注意死锁涉及表 t1 (索引 i1)上的键锁。死锁输出显示哪些进程拥有死锁中涉及的锁,哪些会话在等待锁被授权以及相关联的锁模式。
默认情况下,生成最小日志量的进程将选作死锁牺牲品,并自动回滚。若要影响所回滚的会话,请为会话设置 DEADLOCK_PRIORITY。
名称 | 说明 | 默认值 |
已启用 | 启用或禁用工作流。 | 是 |
优先级 | 定义警报优先级。 | 1 |
严重性 | 定义警报严重性。 | 1 |
Target | Microsoft.SQLServer.2012.DBEngine | ||
Category | EventCollection | ||
Enabled | True | ||
Event_ID | 1205 | ||
Event Source | $Target/Property[Type="SQL!Microsoft.SQLServer.DBEngine"]/ServiceName$ | ||
Alert Generate | True | ||
Alert Severity | Warning | ||
Alert Priority | Normal | ||
Remotable | True | ||
Alert Message |
| ||
Event Log | Application | ||
Comment | Mom2012ID='{5DEC3ED6-3871-44AB-9D4B-2433D8BAA8A5}';MOM2012GroupID={467ECC75-C5DA-42BD-955C-A73BBB51AF74} |
ID | Module Type | TypeId | RunAs |
---|---|---|---|
_F6DA1507_12AF_11D3_AB21_00A0C98620CE_ | DataSource | Microsoft.Windows.EventProvider | Microsoft.SQLServer.SQLDefaultAccount |
GenerateAlert | WriteAction | System.Health.GenerateAlert | Default |
<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>