Logique de nouvelle tentative configurable (JDBC)

Télécharger le pilote JDBC

La logique configurable de nouvelle tentative (CRL) est un mécanisme basé sur des règles qui relance automatiquement les instructions ayant échoué ou les tentatives de connexion initiales en fonction des numéros d’erreur SQL Server que vous choisissez, avec des paramètres de temporisation que vous contrôlez. CRL a été introduit dans Microsoft JDBC Driver 12.10 pour SQL Server.

CRL est distinct de la résilience des connexions inactives et des propriétés connectRetryCount / connectRetryInterval. La résilience inactive récupère de manière transparente les connexions interrompues et connectRetryCount réessaye l’authentification initiale selon une planification fixe pour une liste intégrée d’erreurs temporaires. CRL vous permet de déterminer quelles erreurs peuvent faire l’objet d’une nouvelle tentative, combien de fois et combien de temps attendre entre les tentatives. Vous pouvez utiliser les trois mécanismes ensemble.

Nouvelles tentatives de la CRL

La CRL prend en charge deux scénarios distincts, chacun étant contrôlé par sa propre propriété de connexion :

Scénario Propriété DaLorsque la nouvelle tentative s’exécute Déclenché par
Échec de l’exécution de l’instruction retryExec Lors de l’exécution d’une instruction (par exemple, executeQuery, executeUpdate, executeou exécution par lots) Un SQLServerException dont le numéro d’erreur correspond à une règle d’instruction configurée
Échec de connexion initiale ou d’authentification retryConn À l’intérieur de la boucle de nouvelle tentative de connexion du pilote (qui est fermée par connectRetryCount et loginTimeout) Un SQLServerException lors de l’authentification dont le numéro d’erreur correspond à une règle de connexion configurée, ou, par défaut, toute erreur temporaire déjà couverte par la liste intégrée des nouvelles tentatives

Pour les instructions, le pilote retente uniquement la commande défaillante. Le pilote ne réinitialise pas l’état de la transaction en cours, concevez donc vos règles en fonction des erreurs après lesquelles la session reste utilisable, telles que la victime d’un interblocage (1205) ou l’expiration du délai de verrouillage (1222).

Pour les connexions, CRL complète ou remplace la liste intégrée au pilote des erreurs de connexion temporaires. Consultez les règles de nouvelle tentative de connexion pour la sémantique de + préfixe.

Activer la CRL

La CRL comporte deux couches :

  1. La couche de nouvelle tentative de connexion est activée par défaut : tant que connectRetryCount > 0 (la valeur par défaut est 1), le pilote tente à nouveau la liste d’erreurs de connexion temporaire intégrée.
  2. La couche de personnalisation (vos propres retryExec règles retryConn ) est désactivée par défaut. Les deux propriétés sont des chaînes vides, sauf si vous les définissez. Vous pouvez les définir via l’URL JDBC, un Properties objet ou un SQLServerDataSource. Le pilote supprime les balises englobantes facultatives {...} dans les trois formes.

Les extraits de code Java de cet article omettent les importations et les déclarations de classe par souci de concision.

Dans l’URL JDBC

Chaque règle (ou toute la liste des règles) doit être encapsulée dans des accolades ({...}) car l’URL JDBC utilise ; comme séparateur :

jdbc:sqlserver://server;databaseName=db;retryExec={1205,1222:3,2*2:select,update}
jdbc:sqlserver://server;databaseName=db;retryConn={+<customErrorNumber>}

Avec un objet Properties

Properties props = new Properties();
props.setProperty("user", "...");
props.setProperty("password", "...");
props.setProperty("retryExec", "1205,1222:3,2*2:select,update");
props.setProperty("retryConn", "+<customErrorNumber>");
Connection c = DriverManager.getConnection("jdbc:sqlserver://server;databaseName=db", props);

Avec SQLServerDataSource

Les mêmes setters existent sur l’interface ISQLServerDataSource :

SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("server");
ds.setDatabaseName("db");
ds.setRetryExec("1205,1222:3,2*2:select,update");
ds.setRetryConn("+<customErrorNumber>");

Syntaxe des règles

Une règle unique comporte jusqu’à trois sections séparées par deux points :

<errorNumbers> : <retryTimings> : <queryFilter>
Rubrique Obligatoire ? Sens
errorNumbers Oui Un SQL Server numéro d’erreur, ou plusieurs séparés par des virgules (par exemple, 1205 ou 1205,1222). Pour les règles de connexion, la présence facultative de + en début de ligne indique si les erreurs transitoires déjà présentes sont conservées.
retryTimings Obligatoire pour les règles d'instruction. Omettez les règles de connexion. retryCount[,initialRetryTime[<op>retryChange]]<op> est + (additif) ou * (multiplicatif).
queryFilter Règles d’instruction facultatives uniquement Liste séparée par des virgules de mots clés SQL. Le pilote convertit la valeur en minuscules lors de l’analyse et convertit en minuscules le SQL précédemment exécuté à l’exécution. La règle se déclenche lorsque la liste de filtres jointes contient le premier jeton du SQL exécuté. Omettez la troisième section pour désactiver le filtrage.

Pour utiliser plusieurs règles dans la même propriété, séparez-les ; et encapsulez chaque règle {...} lors de leur placement dans une URL JDBC.

Paramètres de temporisation

Pour une règle de déclaration avec minutages retryCount, initialRetryTime <op> retryChange :

  • retryCount: nombre de tentatives supplémentaires effectuées par le pilote après le premier échec. Une valeur de 0 désactive les nouvelles tentatives. Les valeurs négatives ne sont pas valides.
  • initialRetryTime: nombre de secondes à attendre avant la première nouvelle tentative. La valeur par défaut est 0.
  • <op>: opérateur, qui peut être + ou *. La valeur par défaut est +.
  • retryChange: montant appliqué au calcul des temps d’attente suivants. La valeur par défaut est 2. Lorsque l’opérande est * et retryChange est omis de la règle, le pilote définit retryChange = initialRetryTime.

Important

Si vous fournissez initialRetryTime sans opérande explicite (par exemple), 3,5le pilote utilise les valeurs par défaut pour l’opérande et retryChange (+ et 2). Les temps d’attente ne sont pas constants. Ils augmentent de 2 à chaque nouvelle tentative. Pour obtenir une attente constante, utilisez le formulaire retryCount,N+0 explicite (par exemple). 3,5+0

Le pilote calcule le temps d’attente pour la tentative i (basée sur 0) au moment de l’analyse :

Opérande Attendre la tentative i
+ (additif) initialRetryTime + (retryChange * i)
* (multiplicative) initialRetryTime * (retryChange ^ i)

Exemples de chaînes temporelles :

String retryCount initialRetryTime opérande Réessayer la modification Séquence d’attente (secondes)
3 3 0 (valeur par défaut) + (valeur par défaut) 2 (par défaut) 0, 2, 4
3,5 3 5 + (valeur par défaut) 2 (par défaut) 5, 7, 9
3,5+5 3 5 + 5 5, 10, 15
3,2*2 3 2 * 2 2, 4, 8
4,1* 4 1 * 1 (égal à initialRetryTime car l’opérande est * et retryChange est omis) 1, 1, 1, 1

Une retryTimings section peut contenir au plus une virgule. Plus d’une virgule déclenche R_invalidParameterNumber.

Règles de nouvelle tentative des instructions (retryExec)

Les règles d’instruction relancent l’exécution des instructions ayant échoué. Lorsqu’une instruction lève un SQLServerException, le pilote :

  1. Recherche le numéro de l’erreur à l’origine de l’échec dans l’ensemble de règles de l’instruction analysée.
  2. Si une règle existe et que le nombre actuel de tentatives est inférieur à retryCount, vérifie éventuellement si la dernière instruction SQL exécutée correspond au queryFilter de la règle.
  3. Si tout correspond, le pilote attend waitTimes[retryAttempt] secondes (sous réserve de queryTimeout, voir Interaction avec queryTimeout et connectRetryCount) et réexécute l’instruction.
  4. Si aucune règle ne correspond, le pilote relance l’exception.

Format (déclarations)

{errorNumber(s):retryCount[,initialRetryTime[<op>retryChange]][:queryFilter]}

Les règles de déclaration doivent inclure une section de minutage. retryCount est obligatoire. Une règle qui contient uniquement un numéro d’erreur est interprétée comme une règle de connexion . Par conséquent, pour les instructions, fournissez toujours au moins retryCount.

Exemples (énoncés)

Rule Résultat
{1205:3} Réessayer la victime de l'interblocage (1205) jusqu’à 3 fois, sans attente entre les tentatives.
{1205,1222:3,5+5} Réessayez en cas de victime d’interblocage ou de délai d’expiration du verrouillage, jusqu’à 3 fois, avec des attentes de 5, 10 et 15 secondes.
{2714:2,1*2} Réessayez « l’objet existe déjà » jusqu’à 2 fois, en attendant 1 et 2 secondes.
{1205:4,2+2:select,update} Réessayez uniquement lorsque l’instruction défaillante commence par select ou update.
{1205:3,5+5};{1222:2,2} Deux règles indépendantes, séparées par ;.

Le fait d’énumérer plusieurs numéros d’erreur (par exemple, 1205,1222) constitue une forme abrégée. Le pilote décompose la règle en une entrée par erreur, toutes partageant les mêmes paramètres temporels et le même filtre de requête.

Règles de nouvelle tentative de connexion (retryConn)

Les règles de connexion fonctionnent avec la boucle de nouvelle tentative de connexion existante. Cette boucle est active uniquement lorsque connectRetryCount > 0 (la valeur par défaut est 1). La boucle réessaie déjà une liste intégrée d’erreurs de connexion temporaires à connectRetryInterval secondes d’intervalle, jusqu’à connectRetryCount tentatives supplémentaires, et est limitée à loginTimeout.

Une règle de connexion contient uniquement une section du numéro d’erreur. Il n’a pas de minutage ou de filtre de requête :

{[+]errorNumber(s)}
  • Sans +, les règles configurées remplacent la liste d’erreurs temporaires intégrée. Seules les erreurs que vous listez font l’objet d’une nouvelle tentative.
  • Avec + (par exemple, {+4060}), les règles configurées sont ajoutées à la liste intégrée. Vos erreurs et les valeurs par défaut du pilote sont retentées.

Le mode remplacer-ou-ajouter s’applique globalement à l’ensemble de la valeur retryConn. Si une règle de cette valeur omet +, le pilote bascule pour remplacer le mode pour toutes les règles de cette valeur. Par exemple, retryConn={+4060};{40143} n’ajoute pas 4060 et 40143 à la liste intégrée. La règle 40143 omet +, de sorte que la liste intégrée est abandonnée et que seules 4060 et 40143 sont réessayées. Pour ajouter les deux, écrire retryConn={+4060};{+40143} (ou retryConn={+4060,40143}).

La boucle de connexion continue d’utiliser connectRetryInterval et connectRetryCount pour le rythme et le bornage. La règle CRL élargit ou remplace l’ensemble des erreurs pouvant faire l’objet d’une nouvelle tentative.

Exemples (connexions)

Rule Résultat
{+<customErrorNumber>} Ajoutez un numéro d’erreur personnalisé à la liste d’erreurs temporaire intégrée.
{+<customError1>,<customError2>} Ajoutez plusieurs numéros d’erreur personnalisés à la liste d’erreurs temporaires intégrée.
{4060} Réessayez uniquement l’erreur 4060. Les erreurs transitoires intégrées ne font plus l’objet de nouvelles tentatives par CRL.

Note

retryConn ne modifie loginTimeout pas la sémantique. La boucle de nouvelle tentative de connexion existante limite toujours le temps écoulé total et abandonne tôt si la prochaine connectRetryInterval pousserait le temps écoulé passé loginTimeout.

Liste intégrée des erreurs de connexion transitoires

La boucle de nouvelle tentative de reconnexion réessaie déjà après les erreurs suivantes sans aucune configuration CRL, tant que connectRetryCount > 0. Le fait de lister l’une de ces erreurs dans une règle retryConn avec + est une opération nulle (elles sont déjà prises en compte). Utilisez la règle retryConn lorsque vous devez ajouter une erreur qui ne figure pas dans cette liste, ou lorsque vous devez supprimer entièrement la liste en utilisant la forme no-+ replace.

Note

Vous n'avez pas besoin d'ajouter des erreurs de connexion courantes Azure SQL temporaires telles que 40197, 40501, 40613, 49918, 49919 ou 49920. La liste intégrée les retente déjà.

Error Message Résolution des problèmes
64 Une connexion a été établie avec le serveur, mais une erreur s’est ensuite produite pendant le processus de connexion. (fournisseur : Fournisseur TCP, erreur : 0 - Le nom de réseau spécifié n’est plus disponible.) La connexion TCP a été interrompue en cours de négociation. Il ne s'agit pas d'un échec des Informations d’identification. Si le problème persiste, vérifiez s’il y a une instabilité du réseau côté client, des bogues liés aux fonctions de déchargement de la carte réseau, ou un équipement intermédiaire qui interrompt les connexions à moitié établies.
233 Le client n’a pas pu établir de connexion en raison d’une erreur lors du processus d’initialisation de la connexion avant la connexion. Échec du transport ou du protocole TLS avant connexion. Le serveur retourne généralement ceci lorsqu’il ne peut pas accepter la connexion (épuisement des ressources, connexions maximales atteintes ou client non pris en charge). Il ne s'agit pas d'un échec des Informations d’identification. Vérifiez l’intégrité du serveur, puis vérifiez loginTimeoutles paramètres TLS et la compatibilité des versions du client/serveur TLS.
4060 Impossible d’ouvrir la base de données database_name demandée par la connexion. La connexion a échoué. L’identification a réussi, mais il a été impossible d’ouvrir la base de données demandée. Les causes transitoires comprennent le cas où la base de données est en transition (basculement, restauration, mise à l’échelle verticale) ou est en pause automatique. Les causes persistantes (la base de données n’existe pas, la connexion n’a pas accès) ne seront pas corrigées par nouvelle tentative ; vérifiez le nom de la base de données, le mappage de connexion et l’état de la base de données.
4221 La connexion à read-secondary a échoué en raison d’un délai d’attente trop long sur HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING. La base de données secondaire accessible en lecture n’a pas pu accepter la connexion, car les versions de ligne sont toujours manquantes dans les transactions en cours d’exécution lorsque le réplica a été recyclé. Atténuez le problème en évitant les transactions d’écriture longues sur le serveur principal ; la nouvelle tentative réussit généralement une fois que le serveur principal valide ou annule les transactions ouvertes.
10053 Une erreur au niveau du transport s’est produite lors de l’envoi de la requête au serveur. (fournisseur : Fournisseur TCP, erreur : 0 - Une connexion établie a été abandonnée par le logiciel de votre ordinateur hôte.) Le côté local a abandonné la connexion (Windows SocketsWSAECONNABORTED). Souvent, il s’agit d’un échec du keepalive ou de la pile réseau locale qui ferme une connexion inactive ou semi-ouverte. Vérifiez l’état du réseau côté client, les temporisateurs keepalive du système d’exploitation et tout pare-feu local ou tout client VPN.
10054 Une erreur au niveau du transport s’est produite lors de l’envoi de la requête au serveur. (fournisseur : Fournisseur TCP, erreur : 0 - Une connexion existante a été fermée de force par l’hôte distant.) L’hôte distant a envoyé une réinitialisation TCP (Windows Sockets WSAECONNRESET). Causes courantes : le processus homologue s’est bloqué, un pare-feu a injecté une réinitialisation ou la passerelle Azure SQL a fermé une connexion inactive. Pour les scénarios de réinitialisation après inactivité, activez TCP keepalive côté client ou réduisez le délai d’inactivité du pool de connexions.
10928 ID de ressource : N. La limite de type limite pour la base de données est N et a été atteinte. Voir sys.dm_exec_sessions pour l’utilisation. Une limite de gestion des ressources de la base de données a été atteinte (sessions, processus de travail ou requêtes). Identifiez le type de limite du message, puis réduisez l’accès concurrentiel, augmentez la base de données ou raccourcissez les opérations longues contenant la ressource.
10929 ID de ressource : N. La garantie minimale de type limite est N, la limite maximale est N et l’utilisation actuelle de la base de données est N. Toutefois, le serveur est actuellement trop occupé pour prendre en charge les requêtes supérieures à N pour cette base de données. La base de données dépasse sa garantie minimale et le serveur sous-jacent est limité. Une nouvelle tentative réussit généralement lorsque la charge du voisin tombe. Les occurrences soutenues indiquent que vous avez besoin d’un niveau de service supérieur ou d’un environnement moins bruyant.
40020
40143
40166
40540
Signalé dans l'emplacement Error code %d de l’erreur 40197 lors du basculement. Sous-codes intégrés dans un message de basculement 40197 qui, dans certains cas, apparaissent comme le numéro d’erreur principal. Le pilote les répertorie individuellement afin de réessayer avec l’une ou l’autre forme. Traitez-les comme 40197.
40197 Le service a rencontré une erreur lors du traitement de votre demande. Réessayez. Code d’erreur N. Mise à niveau logicielle, défaillance matérielle ou autre événement de basculement dans Azure SQL. La reconnexion vous redirige vers une réplique intègre. Le code d’erreur intégré identifie le type de basculement. Les occurrences persistantes doivent être signalées avec l’ID de suivi de session.
40501 Le service est actuellement occupé. Relancez la demande dans 10 secondes. ID d’incident : guid. Code : N. Limitation du débit du moteur SQL Azure. Le minimum recommandé est un délai de temporisation de 10 secondes. Une limitation durable indique que vous avez dépassé l’allocation de DTU/vCore ; augmentez les ressources ou réduisez le niveau de simultanéité.
40613 La base de données database_name sur le serveur server_name n’est actuellement pas disponible. Veuillez réessayer la connexion ultérieurement. Si le problème persiste, contactez le support technique et fournissez-lui l’ID de suivi de session du guid. La base de données n’est pas disponible, en général pendant un basculement ou brièvement lors d’une opération de mise à l’échelle. Réessayez après un backoff ; si le problème persiste au-delà de quelques minutes, relevez l’ID de traçage de la session et ouvrez un ticket d’assistance.
42108 Impossible de se connecter au pool SQL, car il est suspendu. Veuillez redémarrer le pool SQL, puis réessayer. Le pool SQL dédié (Synapse) est dans un état suspendu. Réessayer n’est utile que si quelque chose relance le pool en parallèle. Réactivez explicitement le pool ou planifiez l’exécution de la charge de travail après sa réactivation.
42109 Le pool SQL se réchauffe. Réessayez. Le pool SQL dédié reprend. Réessayez après un backoff jusqu’à ce qu’il soit en ligne ; la phase de préchauffe prend généralement quelques minutes.
49918 Impossible de traiter la requête. Ressources insuffisantes pour traiter la demande. Le plan de contrôle n’a pas pu allouer de ressources pour la requête pour le moment. Réessayez après un backoff. Les occurrences persistantes indiquent la pression de capacité régionale.
49919 Impossible de traiter la demande de création ou de mise à jour. Trop d’opérations de création ou de mise à jour en cours pour l’abonnement N. Limite de concurrence au niveau de l’abonnement sur les opérations de gestion. Réduisez les appels de création/mise à jour parallèles ou les décaler.
49920 Impossible de traiter la requête. Trop d’opérations en cours pour l’abonnement N. Limite de concurrence au niveau de l’abonnement sur les opérations en cours de vol. Réduisez le parallélisme ou attendez que les opérations en cours se terminent.

La liste Canonical du pilote est l’enum TransientError dans SQLServerError.java. Le texte du message d’erreur provient de Azure SQL erreurs de connexion temporaires. Les erreurs au niveau des instructions (telles que l’erreur 1205 d'une victime de blocage ou l’erreur 1222 d’expiration du délai de demande de verrouillage) ne figurent pas dans cette liste, car la boucle de nouvelle tentative de connexion ne se déclenche que lors de la connexion initiale. Pour réessayer ces erreurs, utilisez une retryExec règle.

Charger des règles à partir d’un fichier de propriétés

Si vous n’avez pas défini retryExec ou retryConn dans la connexion, CRL recherche un fichier nommé mssql-jdbc.properties à côté du JAR du pilote dans le classpath. Le fichier utilise l’analyse de base key=value . Lignes qui commencent par retryExec= ou retryConn= sont récupérées. Les valeurs utilisent la même syntaxe décrite dans cet article, avec ; la séparation de plusieurs règles.

Utilisez des noms de clés exacts (retryExec et retryConn), sans espace blanc non significatif. Le fichier n'est pas analysé en tant que fichier de propriétés Java complet. Le pilote effectue une vérification littérale startsWith sur chaque ligne, de sorte que :

  • Les lignes qui commencent par # ou tout autre préfixe autre que retryExec/retryConn sont ignorées.
  • Les lignes dont la clé commence uniquement par retryExec ou retryConn (par exemple, retryExec2=...) sont considérées comme la propriété correspondante et peuvent entraîner des erreurs d’analyse. N’introduisez pas de variantes personnalisées.

Exemple mssql-jdbc.properties:

retryExec=1205:3,5+5;1222:2,2
retryConn=+4060,40143

Si le fichier est manquant, CRL consigne un message FINE dans le logger com.microsoft.sqlserver.jdbc.ConfigurableRetryLogic et continue sans règles. Le chemin d’accès au fichier utilisé pour la recherche est inclus dans ce message de journal.

Les valeurs de chaîne de connexion sont prioritaires. Si retryExec ou retryConn ne sont pas vides sur la connexion, le pilote ne consulte pas le fichier pour cette propriété.

Comportement d’actualisation des règles

CRL maintient un seul ensemble de règles à l’échelle de la JVM. Après la construction, le pilote actualise les règles de manière différée :

  • Le pilote évalue les opportunités d’actualisation pendant l’exécution de l’instruction et les nouvelles tentatives de connexion.
  • Une actualisation se produit uniquement après 30 secondes qui se sont écoulées depuis la lecture précédente.
  • Si les règles provenaient à l’origine de mssql-jdbc.properties, le pilote compare l’horodatage de dernière modification du fichier à l’horodatage qu’il a enregistré lors de la lecture précédente. Si le fichier a changé, le pilote l’analyse de nouveau.
  • Si les règles proviennent d’un chaîne de connexion, le pilote réapplique la valeur de chaîne de connexion précédemment stockée.

Ce comportement signifie que les modifications apportées à mssql-jdbc.properties sont prises en compte automatiquement en environ 30 secondes, sans redémarrer l’application.

Important

Étant donné que l’ensemble de règles est un singleton à l’échelle de la JVM, l’ouverture d’une seconde connexion qui définit une valeur différente pour retryExec ou retryConn remplace également les règles de la première connexion. Traitez la configuration CRL comme un paramètre au niveau du processus, et non comme un paramètre par connexion, lorsque plusieurs connexions dans la même JVM sont en désaccord.

Interaction avec queryTimeout et connectRetryCount

Nouvelles tentatives d’instruction et queryTimeout

Lorsqu’une règle d’instruction se déclenche, le pilote compare le temps d’attente suivant à la valeur queryTimeout au niveau de la connexion :

  • Si queryTimeout >= 0ettimeToWait > queryTimeout, le pilote génère R_InvalidRetryInterval au lieu d'effecteur une nouvelle tentative. Le pilote ne relance pas l’erreur d’origine. Cela génère l’erreur de configuration.
  • La propriété de connexion queryTimeout a pour valeur par défaut -1 ; par défaut, la comparaison est donc ignorée et toute attente est autorisée.
  • Le paramètre queryTimeout=0 ne désactive pas cette vérification, car 0 >= 0 il a la valeur true. Tout timeToWait > 0 augmente R_InvalidRetryInterval.

Lorsque vous définissez queryTimeout à une valeur positive, veillez à ce que la valeur de initialRetryTime + (retryCount - 1) * retryChange (additive) ou de initialRetryTime * retryChange^(retryCount-1) (multiplicative) reste inférieure à cette valeur.

Nouvelles tentatives de connexion et connectRetryCountloginTimeout

retryConn n’active pas elle-même les nouvelles tentatives d’authentification. Les propriétés existantes restent en vigueur :

  • connectRetryCount (valeur par défaut 1, plage 0-255) est le nombre de tentatives d’authentification supplémentaires. Définissez-la sur 0 pour désactiver les nouvelles tentatives d’authentification. retryConn n’a aucun effet lorsque connectRetryCount = 0, car le pilote génère une exception dès le premier échec.
  • connectRetryInterval (10 secondes par défaut, plage de 1 à 60) est l’attente entre les tentatives. Le premier nouvel essai a lieu immédiatement.
  • loginTimeout est la limite globale. Le pilote abandonne dès le début si l’intervalle suivant pousse le temps écoulé.loginTimeout

Pour plus d’informations, consultez Résilience de connexion (JDBC).

Exemples

Survivre aux blocages et aux délais d’expiration des verrouillages sur les écritures

jdbc:sqlserver://server;databaseName=db;retryExec={1205,1222:4,2*2:insert,update,delete,merge}

Jusqu’à quatre nouvelles tentatives pour la une victime de blocage (1205) ou le délai d’expiration du verrouillage (1222), avec une interruption de 2, 4, 8 et 16 secondes, mais uniquement pour les instructions d’écriture.

Relancer la création du schéma pendant les opérations en ligne

retryExec={2714:2,1+1};{3702:2,1+1}

Réessaie en cas d’erreurs 2714 (object already exists) et 3702 (cannot drop database currently in use) deux fois chacune, avec des délais d’attente de 1 puis 2 secondes.

Ajouter une erreur personnalisée à la liste d’erreurs temporaires

retryConn={+<customErrorNumber>}

Ajoute un numéro d’erreur personnalisé qui n’est pas déjà dans la liste intégrée. Si vous ajoutez une erreur transitoire Azure SQL intégrée, telle que 40197, 40501, 40613, 49918, 49919 ou 49920, cela ne change rien, car le pilote effectue déjà automatiquement de nouvelles tentatives.

Configurer la CRL à l’aide d’un fichier de propriétés

Placez mssql-jdbc.properties à côté du fichier JAR du pilote :

retryExec=1205:3,5+5:select,update
retryConn=+<customErrorNumber>

Ne définissez pas retryExec ni retryConn dans la connexion. Le pilote lit les règles du fichier et relecture après chaque modification (vérifiée une fois toutes les 30 secondes).

Résoudre les problèmes de CRL

Activez la journalisation FINE (ou plus détaillée) sur le journaliseur com.microsoft.sqlserver.jdbc.ConfigurableRetryLogic pour voir les tentatives de lecture de fichiers et les décisions d’analyse syntaxique :

com.microsoft.sqlserver.jdbc.ConfigurableRetryLogic.level=FINE

Erreurs de configuration courantes :

Clé du message d’erreur Cause
R_invalidParameterNumber Un jeton non numérique est apparu où le pilote attendait un numéro d’erreur ou un paramètre de minutage, ou retryTimings contenait plusieurs virgules.
R_InvalidRuleFormat La règle comportait plus de 3 sections séparées par deux-points.
R_InvalidRetryInterval Le temps d’attente calculé d’une règle d’instruction dépasse queryTimeout. Réduisez le temps d’attente ou augmentez queryTimeout.
R_PathInvalid ou R_URLInvalid Le pilote n’a pas pu déterminer un chemin d’accès pour rechercher mssql-jdbc.properties.
R_errorReadingStream Erreur d’E/S lors de la lecture de mssql-jdbc.properties.

Note

Le texte d’un message R_invalidParameterNumber est Le numéro de paramètre {0} n’est pas valide, c’est la même chaîne de ressources que le pilote utilise pour les erreurs de liaison de paramètres d’instructions préparées. Lorsque CRL la génère, la valeur incriminée est le jeton de votre règle de nouvelle tentative (par exemple, un numéro d’erreur ou un élément de temporisation qui n’est pas numérique), et non un index de paramètre PreparedStatement.

Éléments à vérifier lorsqu’une règle ne se déclenche pas :

  1. L’exception SQLServerError.getErrorNumber() correspond réellement au nombre dans votre règle. SQL Server peut associer certains échecs à différents numéros selon le contexte (par exemple, interblocage ou délai d’expiration de verrouillage).
  2. Pour les règles d’instruction avec un queryFilter, le premier jeton délimité par des espaces blancs de l'instruction SQL que vous avez exécutée (en minuscules) se trouve dans la liste de filtres. Les commentaires et WITH les CTE modifient le premier jeton.
  3. retryCount les tentatives de nouvelle exécution correspondent à des tentatives supplémentaires. La première exécution ne compte pas.
  4. Pour les règles de connexion, connectRetryCount est supérieure à 0 et loginTimeout laisse place à au moins un autre connectRetryInterval.
  5. La règle a la forme appropriée. Les règles de déclaration nécessitent une section de temporisation. Les règles de connexion ne doivent pas.