Cette erreur se produit quand Microsoft® SQL Server™ rencontre un interblocage. Un interblocage se produit quand deux processus (ou plus) tentent d'accéder à une ressource pour laquelle l'autre processus détient un verrou. Étant donné que chaque processus a une demande pour une autre ressource, aucun processus ne peut se terminer. Quand un interblocage est détecté, SQL Server annule la commande dont la durée de traitement est la plus courte et retourne le message d'erreur 1205 à l'application cliente. Cette erreur n'est pas irrécupérable et ne peut pas provoquer la fin du lot.
Dans certains cas, une condition d'interblocage peut être à l'origine du renvoi de FAIL par la fonction DB-Library (dbsqlexec, dbsqlok, dbresults ou dbnextrow). Le programme doit toujours vérifier les codes de retour de chaque fonction DB-Library. Si FAIL est renvoyé par une de ces fonctions DB-Library, le programme doit annuler le lot et ne doit pas essayer de continuer. Dans certains cas, il est possible de continuer l'exécution des fonctions suivantes du lot. Cependant, étant donné qu'une situation d'interblocage est survenue et que les fonctions qui l'ont provoquée ont été annulées, les fonctions ultérieures du traitement par lots risquent fortement d'échouer avec une erreur plus grave, comme « Objet introuvable ».
Dans d'autres cas, une condition de blocage ne provoquera pas le renvoi de FAIL par une fonction DB-Library. Dans ces cas, le programme doit vérifier si le gestionnaire de messages contient le message d'erreur 1205 et utiliser la fonction dbsetuserdata pour le communiquer à l'application. Le programme doit ensuite vérifier l'indicateur de blocage après chaque appel de fonction DB-Library et annuler le traitement par lots si un blocage est détecté.
Si cela peut sembler inutile d'annuler un traitement par lots après avoir reçu un message d'interblocage 1205, c'est néanmoins nécessaire car le serveur n'arrête pas toujours le traitement par lots dans une situation d'interblocage. Si le traitement par lots n'est pas annulé, toute tentative d'envoi d'un nouveau lot peut se terminer par l'erreur DB-Library 10038 « Résultats en attente ».
Vous pouvez également utiliser l'instruction SET DEADLOCK_PRIORITY (LOW ou NORMAL). SET DEADLOCK_PRIORITY contrôle la réaction de la session en cas de blocage. Avec LOW, le processus sera la victime privilégiée d'un blocage. Avec NORMAL, la session utilisera la méthode par défaut de traitement des blocages.
Lorsqu'un blocage n'est pas résolu, il s'avère souvent utile d'utiliser l'indicateur de trace 1204 pour collecter plus d'informations. L'indicateur de trace 1204 imprime les chaînes et la victime du blocage, comme indiqué dans l'exemple de résultat :
*** Interblocage détecté *** == Processus 7 choisi comme victime de l'interblocage == Interblocage détecté à : 1998-09-10 16:39:29.17 == Informations sur les sessions impliquées : SPID : 7 ECID : 0 Type d'instruction : UPDATE Tampon d'entrée : update t1 set c1 = c1 where c1 = 2 SPID : 8 ECID : 0 Type d'instruction : UPDATE Tampon d'entrée : update t1 set c1 = c1 where c1 = 1 == Informations sur les verrous d'interblocage impliqués : == Verrou : CLÉ : 2:117575457:1 (010001000000) Base de données : tempdb Table : t1 Index : i1 - Détenu par : SPID 7 ECID 0 Mode "S" - Demandé par : SPID 8 ECID 0 Mode "X" == Verrou : CLÉ : 2:117575457:1 (020002000000) Base de données : tempdb Table : t1 Index : i1 - Détenu par : SPID 8 ECID 0 Mode "S" - Demandé par : SPID 7 ECID 0 Mode "X"
Ces informations de blocage peuvent être interprétées comme suit :
La première section indique la victime et l'heure du blocage, ainsi que les sessions concernées. Pour chaque session, le SPID en cours, le type d'instruction et une partie du tampon d'entrée sont affichés.
La deuxième section contient des détails sur les verrous impliqués dans l'interblocage. Dans le résultat ci-dessus, notez que le blocage concerne des verrous de clé dans la table t1, index i1. La sortie de l'interblocage montre les processus qui détiennent les verrous impliqués dans l'interblocage et les sessions en attente des verrous devant être octroyés ainsi que les modes de verrouillage associés.
Par défaut, le processus ayant généré le moins de données dans le journal est choisi comme victime de l'interblocage et est annulé automatiquement. Pour influencer le choix de la session à annuler, définissez DEADLOCK_PRIORITY pour une session.
Nom | Description | Valeur par défaut |
Activé | Active ou désactive le flux de travail. | Oui |
Priorité | Définit la priorité de l'alerte. | 1 |
Gravité | Définit la gravité de l'alerte. | 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>