Эта ошибка возникает, когда Microsoft® SQL Server™ обнаруживает взаимоблокировку. Взаимоблокировка возникает, когда каждый из двух (или более) процессов пытается получить доступ к ресурсу, заблокированному другим процессом. Так как каждый процесс запрашивает другой ресурс, ни один из процессов не может завершиться. При обнаружении взаимоблокировки SQL Server выполняет откат команды с наименьшим временем обработки и возвращает клиентскому приложению сообщение об ошибке 1205. Эта ошибка не является неустранимой и не обязательно вызывает прекращение выполнения пакета.
В некоторых случаях состояние взаимоблокировки приводит к тому, что функция DB-Library (например, dbsqlexec, dbsqlok, dbresults или dbnextrow) возвращает значение FAIL. За проверку кодов, возвращаемых каждой функцией, всегда отвечает программа. Если значение FAIL возвращено одной из таких функций DB-Library, программа должна прервать обработку данного пакета, не пытаясь продолжить. В некоторых случаях продолжить выполнение последующих функций в пакете возможно. Однако после взаимоблокировки производится откат вызвавших его функций, поэтому выполнение последующих функций в пакете, скорее всего, завершится с более серьезной ошибкой, например "объект не найден".
В других ситуациях при возникновении состояния взаимоблокировки функция 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.2008.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 | Mom2008ID='{5DEC3ED6-3871-44AB-9D4B-2433D8BAA8A5}';MOM2008GroupID={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.2008.Transaction_was_deadlocked_on_resources_with_another_process_and_has_been_chosen_as_the_deadlock_victim._Rerun_the_transaction_1_5_Rule" Target="SQL2008Core!Microsoft.SQLServer.2008.DBEngine" Enabled="true" ConfirmDelivery="true" Remotable="true" Comment="Mom2008ID='{5DEC3ED6-3871-44AB-9D4B-2433D8BAA8A5}';MOM2008GroupID={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.2008.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>