Este error se produce cuando Microsoft® SQL Server™ encuentra un interbloqueo. Un interbloqueo se produce cuando dos (o más) procesos intentan tener acceso a un recurso que otro proceso mantiene bloqueado. Dado que cada proceso posee una solicitud para otro recurso, no se podrá procesar ninguno de los procesos. Cuando se detecta un interbloqueo, SQL Server revierte el comando con el menor tiempo de procesamiento y devuelve el mensaje de error 1205 a la aplicación cliente. Este error no es grave y podría no ser la causa de que finalice el lote.
En algunas instancias, una condición de interbloqueo dará lugar a que una función DB-Library (como dbsqlexec, dbsqlok, dbresults o dbnextrow) devuelva un error. Siempre es responsabilidad del programa comprobar los códigos de retorno de cada función DB-Library. Si alguna de estas funciones de DB-Library devuelve un error, el programa debe cancelar el lote y no intentar continuar. En algunos casos, es posible seguir con la ejecución de las funciones posteriores del lote. No obstante, ya que se ha producido una situación de interbloqueo y las funciones que la provocaron se han revertido, las funciones posteriores del lote devolverán un error más grave, como "objeto no encontrado".
En otras instancias, una condición de interbloqueo no provocará que la función DB-Library devuelva un error. En tales casos, el programa debe comprobar si existe algún mensaje de error 1205 en el controlador de mensajes y usar la función dbsetuserdata para comunicárselo a la aplicación. A continuación, el programa debe comprobar el indicador de interbloqueo después de cada llamada a DB-Library y deberá cancelar el lote si se detecta un interbloqueo.
Aunque puede parecer innecesario cancelar un lote después de recibir un mensaje de interbloqueo 1205, es necesario porque el servidor no siempre termina el lote cuando se produce una situación de interbloqueo. Si no se cancela el lote, cualquier intento de enviar un lote nuevo puede dar lugar a un error de DB-Library 10038 de resultados pendientes.
También puede usar la instrucción SET DEADLOCK_PRIORITY (LOW o NORMAL). SET DEADLOCK_PRIORITY controla cómo reacciona la sesión cuando se produce una situación de interbloqueo. Si se establece en LOW, el proceso será el objetivo preferido del interbloqueo. Si se define en NORMAL, la sesión usará un método de control de interbloqueos predeterminado.
Si una situación de interbloqueo persiste, suele ser útil usar una marca de seguimiento 1204 para recopilar más información. Esta marca imprime las cadenas y el sujeto de interbloqueo como se muestra a continuación:
*** 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"
Esta información de interbloqueo puede interpretarse del siguiente modo:
La primera sección muestra el sujeto y el tiempo del interbloqueo junto con las sesiones implicadas en el interbloqueo. Para cada sesión, se mostrará el SPID actual, el tipo de instrucción y una parte del búfer de entrada.
En la segunda sección se incluyen los detalles de los bloqueos implicados en el interbloqueo. En el ejemplo anterior, observe que el interbloqueo afecta a bloqueos de clave en la tabla t1, índice i1. El resultado del interbloqueo muestra cuáles son los procesos a los que pertenecen los bloqueos del interbloqueo y qué sesiones están a la espera de que se concedan los bloqueos así como los modos de bloqueo asociados.
El proceso que ha generado la cantidad inferior de volumen de registro se elegirá, de forma predeterminada, como el objetivo del bloqueo y se revertirá automáticamente. Para determinar qué sesión se revertirá, establezca DEADLOCK_PRIORITY para una sesión.
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>