Эта ошибка возникает, когда 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 выводит цепочки взаимоблокировки и цель (см. следующий пример выходных данных):
*** Обнаружена взаимоблокировка *** == процесс 7 выбран в качестве цели взаимоблокировки == взаимоблокировка обнаружена в 1998-09-10 16:39:29.17 == сведения об участнике сеанса: SPID: 7 ECID: 0 Тип инструкции: UPDATE Входной буфер: обновить t1 задать c1 = c1 где c1 = 2 SPID: 8 ECID: 0 Тип инструкции: UPDATE Входной буфер: обновить t1 задать c1 = c1 где c1 = 1 == сведения об участнике взаимоблокировки: == блокировка: KEY: 2:117575457:1 (010001000000) База данных: tempdb Таблица: t1 Индекс: i1 — принадлежит: SPID 7 ECID 0 Режим S — запрошено: SPID 8 ECID 0 Режим X == блокировка: KEY: 2:117575457:1 (020002000000) База данных: tempdb Таблица: t1 Индекс: i1 — принадлежит: SPID 8 ECID 0 Режим S — запрошено: SPID 7 ECID 0 Режим X
Эти сведения о взаимоблокировке можно интерпретировать следующим образом.
В первом разделе отображается цель взаимоблокировки и время взаимоблокировки вместе с разделами, вовлеченными в данную взаимоблокировку. Для каждого сеанса отображаются текущий код SPID, тип инструкции и часть входного буфера.
Во втором разделе отображаются сведения о блокировках, вовлеченных в данную взаимоблокировку. В приведенных выше выходных данных обратите внимание на то, что взаимоблокировка включает блокировки ключей в таблице t1 с индексом i1. В выходных данных взаимоблокировки указывается, какие процессы владеют вовлеченными в нее взаимоблокировками и какие сеансы ожидают предоставления блокировок, а также связанные режимы блокировок.
Процесс, создавший том журнала наименьшего размера, по умолчанию выбирается в качестве цели взаимоблокировки. Его откат выполняется автоматически. Чтобы повлиять на выбор сеансов для отката, задайте для них параметр DEADLOCK_PRIORITY.
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>$Data/EventDescription$</AlertParameter1>
</AlertParameters>
<Suppression>
<SuppressionValue/>
</Suppression>
</WriteAction>
</WriteActions>
</Rule>