Partager via


Instructions pour la logique de nouvelle tentative pour les transactions sur les tables Memory-Optimized

Certaines situations d’erreur surviennent lors de transactions accédant à des tables optimisées pour la mémoire.

    1. La transaction actuelle a tenté de mettre à jour un enregistrement mis à jour depuis le démarrage de la transaction.
    1. La transaction actuelle n’a pas pu être validée en raison d’un échec de validation de lecture reproductible.
    1. La transaction actuelle n’a pas pu être validée en raison d’un échec de validation sérialisable.
    1. Une transaction précédente dont dépendait la transaction actuelle a été annulée, et la transaction actuelle ne peut plus être validée.

Une cause courante de ces erreurs est l’interférence entre l’exécution simultanée de la transaction. L’action corrective courante consiste à réessayer la transaction.

Pour plus d’informations sur ces conditions d’erreur, consultez la section sur la détection de conflits, la validation et la vérification des dépendances de validation dans Transactions dans les tables Memory-Optimized.

Les interblocages (code d’erreur 1205) ne peuvent pas se produire pour les tables optimisées en mémoire. Les verrous ne sont pas utilisés pour les tables optimisées en mémoire. Toutefois, si l’application contient déjà une logique de nouvelle tentative pour les interblocages, la logique existante peut être étendue pour inclure les nouveaux codes d’erreur.

Considérations relatives à la nouvelle tentative

Les applications rencontrent généralement des conflits entre les transactions et doivent implémenter une logique de nouvelle tentative pour résoudre ces conflits. Le nombre de conflits rencontrés dépend d’un certain nombre de facteurs :

  • Conflit pour chaque ligne. Le risque de conflits augmente à mesure que le nombre de transactions qui tentent de mettre à jour la même ligne augmente.

  • Nombre de lignes lues par des transactions REPEATABLE READ. Plus les lignes sont lues, plus certaines de ces lignes sont mises à jour par des transactions simultanées. Cela provoque des échecs de validation de lecture reproductibles.

  • Taille des plages d’analyse utilisées par les transactions SERIALIZABLE. Plus les plages d’analyse sont élevées, plus les transactions simultanées introduisent des lignes fantômes, ce qui entraîne des échecs de validation sérialisables.

    Il est difficile pour une application d’éviter ces conflits, nécessitant une logique de nouvelle tentative.

Important

Les transactions en lecture-écriture qui accèdent aux tables optimisées en mémoire nécessitent une logique de nouvelle tentative.

Considérations relatives aux transactions Read-Only et aux procédures stockées compilées en mode natif

Les transactions en lecture seule qui s’étendent sur une seule exécution d’une procédure stockée compilée en mode natif ne nécessitent pas de validation pour les transactions REPEATABLE READ et SERIALIZABLE. Les conflits d'écriture ne peuvent pas se produire parce qu'une transaction est en lecture seule.

Toutefois, les défaillances de dépendance peuvent toujours se produire. Les échecs de dépendance sont plus rares que les erreurs résultant de conflits. Par conséquent, dans de nombreux cas, une logique de nouvelle tentative spécifique n’est pas nécessaire pour les transactions en lecture seule qui s’étendent sur des exécutions uniques de procédures stockées compilées en mode natif.

Considérations relatives aux transactions Read-Only et aux transactions entre conteneurs

Les transactions inter-conteneurs en lecture seule, qui sont des transactions démarrées en dehors du contexte d’une procédure stockée compilée en mode natif, n’effectuent pas de validation si les tables optimisées en mémoire sont toutes accessibles sous isolation SNAPSHOT. Toutefois, lorsque des tables optimisées en mémoire sont accessibles sous l’isolation REPEATABLE READ ou SERIALIZABLE, la validation est effectuée au moment de la validation. Dans ce cas, la logique de nouvelle tentative peut être nécessaire.

Pour plus d’informations, consultez la section sur les transactions entre conteneurs dans les niveaux d’isolation des transactions.

Implémentation de la logique de nouvelle tentative

Comme pour toutes les transactions qui accèdent aux tables optimisées en mémoire, vous devez envisager une logique de nouvelle tentative pour gérer les défaillances potentielles, telles que les conflits d’écriture (code d’erreur 41302) ou les échecs de dépendance (code d’erreur 41301). Dans la plupart des applications, le taux d’échec est faible, mais il est toujours nécessaire de gérer les défaillances en réessayant la transaction. Deux méthodes suggérées d’implémentation de la logique de nouvelle tentative sont les suivantes :

  • Nouvelles tentatives côté client. Les nouvelles tentatives côté client sont la méthode recommandée pour implémenter la logique de nouvelle tentative dans le cas général. L’application cliente intercepte l’erreur levée par la transaction et réessaye la transaction. Si une application cliente existante a une logique de nouvelle tentative pour gérer les interblocages, vous pouvez étendre l’application pour gérer les nouveaux codes d’erreur.

  • Utilisation d'une procédure stockée avec enveloppe. Le client appelle une procédure stockée interprétée Transact-SQL qui appelle la procédure stockée compilée en mode natif ou exécute la transaction. La procédure wrapper utilise ensuite la logique try/catch pour intercepter l’erreur et réessayer l’appel de procédure si nécessaire. Il est possible que les résultats soient envoyés au client avant l’échec, et que le client ne saurait pas les ignorer. Par conséquent, pour être sûr, il est préférable d’utiliser cette méthode uniquement avec des procédures stockées compilées en mode natif qui ne retournent aucun jeu de résultats au client.

La logique de nouvelle tentative peut être implémentée dans Transact-SQL ou dans le code de l’application dans le niveau intermédiaire.

Deux raisons possibles de prendre en compte la logique de nouvelle tentative sont les suivantes :

  • L’application cliente a une logique de nouvelle tentative pour d’autres codes d’erreur, tels que 1205, que vous pouvez étendre.

  • Les conflits sont rares et il est important de réduire la latence de bout en bout à l’aide de l’exécution préparée. Pour plus d’informations sur l’exécution directe de procédures stockées compilées en mode natif, consultez Procédures stockées compilées en mode natif.

L’exemple suivant montre une logique de nouvelle tentative dans une procédure stockée interprétée Transact-SQL qui contient un appel à une procédure stockée compilée en mode natif ou à une transaction entre conteneurs.

CREATE PROCEDURE usp_my_procedure @param1 type1, @param2 type2, ...  
AS  
BEGIN  
  -- number of retries - tune based on the workload  
  DECLARE @retry INT = 10  
  
  WHILE (@retry > 0)  
  BEGIN  
    BEGIN TRY  
  
      -- exec usp_my_native_proc @param1, @param2, ...  
  
      --       or  
  
      -- BEGIN TRANSACTION  
      --   ...  
      -- COMMIT TRANSACTION  
  
      SET @retry = 0  
    END TRY  
    BEGIN CATCH  
      SET @retry -= 1  
  
      -- the error number for deadlocks (1205) does not need to be included for   
      -- transactions that do not access disk-based tables  
      IF (@retry > 0 AND error_number() in (41302, 41305, 41325, 41301, 1205))  
      BEGIN  
        -- these error conditions are transaction dooming - rollback the transaction  
        -- this is not needed if the transaction spans a single native proc execution  
        --   as the native proc will simply rollback when an error is thrown   
        IF XACT_STATE() = -1  
          ROLLBACK TRANSACTION  
  
        -- use a delay if there is a high rate of write conflicts (41302)  
        --   length of delay should depend on the typical duration of conflicting transactions  
        -- WAITFOR DELAY '00:00:00.001'  
      END  
      ELSE  
      BEGIN  
        -- insert custom error handling for other error conditions here  
  
        -- throw if this is not a qualifying error condition  
        ;THROW  
      END  
    END CATCH  
  END  
END  

Voir aussi

Présentation des transactions sur les tables Memory-Optimized
Transactions dans les tables Memory-Optimized
Instructions pour les niveaux d’isolation des transactions avec des tables Memory-Optimized