Partager via


Travailler avec Change Tracking (SQL Server)

Les applications qui utilisent le suivi des modifications doivent être en mesure d’obtenir des modifications suivies, d’appliquer ces modifications à un autre magasin de données et de mettre à jour la base de données source. Cette rubrique décrit comment effectuer ces tâches et le rôle que joue le suivi des modifications lorsque un basculement se produit et qu'une base de données doit être restaurée à partir d'une sauvegarde.

Obtenir des modifications à l’aide des fonctions de suivi des modifications

Décrit comment utiliser les fonctions de suivi des modifications pour obtenir des modifications et des informations sur les modifications apportées à une base de données.

À propos des fonctions de suivi des modifications

Les applications peuvent utiliser les fonctions suivantes pour obtenir les modifications apportées à une base de données et les informations concernant ces modifications.

CHANGETABLE(CHANGES ...) fonction
Cette fonction d’ensemble de lignes est utilisée pour rechercher des informations de modification. La fonction interroge les données stockées dans les tables de suivi des modifications internes. La fonction retourne un jeu de résultats qui contient les clés primaires des lignes qui ont changé avec d’autres informations de modification telles que l’opération, les colonnes mises à jour et la version de la ligne.

CHANGETABLE(CHANGES ...) prend une dernière version de synchronisation en tant qu’argument. La dernière version de sychronization est obtenue à l’aide de la @last_synchronization_version variable. La sémantique de la dernière version de synchronisation est la suivante :

  • Le client appelant a obtenu des modifications et connaît toutes les modifications jusqu’à la dernière version de synchronisation.

  • CHANGETABLE(CHANGES ...) retourne donc toutes les modifications qui se sont produites après la dernière version de synchronisation.

    L’illustration suivante montre comment CHANGETABLE(CHANGES ...) est utilisé pour obtenir des modifications.

    Exemple de sortie de requête de suivi des modifications

fonction CHANGE_TRACKING_CURRENT_VERSION()
Permet d’obtenir la version actuelle qui sera utilisée la prochaine fois lors de l’interrogation des modifications. Cette version représente la version de la dernière transaction validée.

CHANGE_TRACKING_MIN_VALID_VERSION() Function
Permet d’obtenir la version minimale valide qu’un client peut avoir et toujours obtenir des résultats valides de CHANGETABLE(). Le client doit vérifier la dernière version de synchronisation par rapport à la valeur retournée par cette fonction. Si la dernière version de synchronisation est inférieure à la version retournée par cette fonction, le client ne pourra pas obtenir les résultats valides de CHANGETABLE() et devra réinitialiser.

Obtention des données initiales

Avant qu’une application puisse obtenir des modifications pour la première fois, l’application doit envoyer une requête pour obtenir les données initiales et la version de synchronisation. L’application doit obtenir les données appropriées directement à partir de la table, puis utiliser CHANGE_TRACKING_CURRENT_VERSION() pour obtenir la version initiale. Cette version sera transmise à CHANGETABLE(CHANGES ...) la première fois que les modifications sont obtenues.

L’exemple suivant montre comment obtenir la version de synchronisation initiale et le jeu de données initial.

    -- Obtain the current synchronization version. This will be used next time that changes are obtained.  
    SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();  
  
    -- Obtain initial data set.  
    SELECT  
        P.ProductID, P.Name, P.ListPrice  
    FROM  
        SalesLT.Product AS P  

Utilisation des fonctions de suivi des modifications pour obtenir les modifications

Pour obtenir les lignes modifiées d’une table et des informations sur les modifications, utilisez CHANGETABLE(CHANGES...). Par exemple, la requête suivante obtient les modifications de la SalesLT.Product table.

SELECT  
    CT.ProductID, CT.SYS_CHANGE_OPERATION,  
    CT.SYS_CHANGE_COLUMNS, CT.SYS_CHANGE_CONTEXT  
FROM  
    CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT  
  

En règle générale, un client souhaite obtenir les données les plus récentes d’une ligne au lieu des clés primaires de la ligne. Par conséquent, une application joint les résultats de CHANGETABLE(CHANGES ...) aux données de la table utilisateur. Par exemple, la requête suivante établit une jointure avec la table SalesLT.Product afin d'obtenir les valeurs des colonnes Name et ListPrice . Notez l'utilisation de OUTER JOIN. Cela est nécessaire afin de s'assurer que les informations relatives aux modifications sont retournées pour les lignes qui ont été supprimées de la table utilisateur.

SELECT  
    CT.ProductID, P.Name, P.ListPrice,  
    CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,  
    CT.SYS_CHANGE_CONTEXT  
FROM  
    SalesLT.Product AS P  
RIGHT OUTER JOIN  
    CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT  
ON  
    P.ProductID = CT.ProductID  

Pour obtenir la version à utiliser dans l’énumération de modification suivante, utilisez CHANGE_TRACKING_CURRENT_VERSION(), comme illustré dans l’exemple suivant.

SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION()  

Lorsqu’une application obtient des modifications, elle doit utiliser CHANGETABLE(CHANGES...) et CHANGE_TRACKING_CURRENT_VERSION(), comme illustré dans l’exemple suivant.

-- Obtain the current synchronization version. This will be used the next time CHANGETABLE(CHANGES...) is called.  
SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();  
  
-- Obtain incremental changes by using the synchronization version obtained the last time the data was synchronized.  
SELECT  
    CT.ProductID, P.Name, P.ListPrice,  
    CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,  
    CT.SYS_CHANGE_CONTEXT  
FROM  
    SalesLT.Product AS P  
RIGHT OUTER JOIN  
    CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT  
ON  
    P.ProductID = CT.ProductID  

Numéros de version

Une base de données sur laquelle le suivi des modifications est activé a un compteur de version qui augmente à mesure que les modifications sont apportées aux tables suivies. Chaque ligne modifiée a un numéro de version qui lui est associé. Lorsqu’une demande est envoyée à une application pour rechercher des modifications, une fonction est appelée qui fournit un numéro de version. La fonction retourne des informations sur toutes les modifications apportées depuis cette version. À certains égards, la version de suivi des modifications est similaire en concept au type de données rowversion.

Validation de la dernière version synchronisée

Les informations sur les modifications sont conservées pendant une durée limitée. La durée est contrôlée par le paramètre CHANGE_RETENTION qui peut être spécifié dans le cadre de ALTER DATABASE.

N’oubliez pas que l’heure spécifiée pour CHANGE_RETENTION détermine la fréquence à laquelle toutes les applications doivent demander des modifications à partir de la base de données. Si une application a une valeur pour last_synchronization_version antérieure à la version de synchronisation valide minimale d’une table, cette application ne peut pas effectuer d’énumération de modifications valide. Cela est dû au fait que certaines informations de modification ont peut-être été nettoyées. Avant qu’une application obtienne des modifications à l’aide de CHANGETABLE(CHANGES ...), l’application doit valider la valeur de last_synchronization_version qu’elle envisage de passer à CHANGETABLE(CHANGES ...). Si la valeur de last_synchronization_version n’est pas valide, cette application doit réinitialiser toutes les données.

L’exemple suivant montre comment vérifier la validité de la valeur de last_synchronization_version pour chaque table.

-- Check individual table.  
IF (@last_synchronization_version < CHANGE_TRACKING_MIN_VALID_VERSION(  
                                   OBJECT_ID('SalesLT.Product')))  
BEGIN  
  -- Handle invalid version and do not enumerate changes.  
  -- Client must be reinitialized.  
END  

Comme l’illustre l’exemple suivant, la validité de la valeur de last_synchronization_version peut être vérifiée sur toutes les tables de la base de données.

-- Check all tables with change tracking enabled  
IF EXISTS (  
  SELECT COUNT(*) FROM sys.change_tracking_tables  
  WHERE min_valid_version > @last_synchronization_version )  
BEGIN  
  -- Handle invalid version & do not enumerate changes  
  -- Client must be reinitialized  
END  

Utilisation du suivi des colonnes

Le suivi des colonnes permet aux applications d’obtenir les données des seules colonnes qui ont changé au lieu de toute la ligne. Par exemple, considérez le scénario dans lequel une table a une ou plusieurs colonnes volumineuses, mais rarement modifiées ; et possède également d’autres colonnes qui changent fréquemment. Sans suivi des colonnes, une application ne peut déterminer qu’une ligne a changé et doit synchroniser toutes les données qui incluent les données de colonne volumineuses. Toutefois, à l’aide du suivi des colonnes, une application peut déterminer si les données de colonne volumineuses ont changé et synchronisent uniquement les données si elles ont changé.

Les informations de suivi des colonnes s’affichent dans la colonne SYS_CHANGE_COLUMNS retournée par la fonction CHANGETABLE(CHANGES ...) .

Le suivi des colonnes peut être utilisé afin que NULL soit retourné pour une colonne qui n’a pas changé. Si la colonne peut être modifiée en NULL, une colonne distincte doit être retournée pour indiquer si la colonne a changé.

Dans l’exemple suivant, la CT_ThumbnailPhoto colonne sera NULL si cette colonne n’a pas changé. Cette colonne peut également être NULL due au fait qu’elle a été modifiée NULL : l’application peut utiliser la CT_ThumbNailPhoto_Changed colonne pour déterminer si la colonne a changé.

DECLARE @PhotoColumnId int = COLUMNPROPERTY(  
    OBJECT_ID('SalesLT.Product'),'ThumbNailPhoto', 'ColumnId')  
  
SELECT  
    CT.ProductID, P.Name, P.ListPrice, -- Always obtain values.  
    CASE  
           WHEN CHANGE_TRACKING_IS_COLUMN_IN_MASK(  
                     @PhotoColumnId, CT.SYS_CHANGE_COLUMNS) = 1  
            THEN ThumbNailPhoto  
            ELSE NULL  
      END AS CT_ThumbNailPhoto,  
      CHANGE_TRACKING_IS_COLUMN_IN_MASK(  
                     @PhotoColumnId, CT.SYS_CHANGE_COLUMNS) AS  
                                   CT_ThumbNailPhoto_Changed  
     CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,  
     CT.SYS_CHANGE_CONTEXT  
FROM  
     SalesLT.Product AS P  
INNER JOIN  
     CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT  
ON  
     P.ProductID = CT.ProductID AND  
     CT.SYS_CHANGE_OPERATION = 'U'  

Obtention de résultats cohérents et corrects

L’obtention des données modifiées pour une table nécessite plusieurs étapes. N’oubliez pas que des résultats incohérents ou incorrects peuvent être retournés si certains problèmes ne sont pas pris en compte et gérés.

Par exemple, pour obtenir les modifications apportées à une table Sales et SalesOrders, une application effectue les étapes suivantes :

  1. Validez la dernière version synchronisée à l'aide de la fonction CHANGE_TRACKING_MIN_VALID_VERSION().

  2. Obtenez la version qui peut être utilisée pour obtenir la modification la prochaine fois à l’aide de CHANGE_TRACKING_CURRENT_VERSION().

  3. Obtenez les modifications de la table Sales en utilisant CHANGETABLE(CHANGES ...).

  4. Obtenez les modifications de la table SalesOrders à l’aide de CHANGETABLE(CHANGES ...).

Deux processus se produisent dans la base de données qui peuvent affecter les résultats retournés par les étapes précédentes :

  • Le processus de nettoyage s’exécute en arrière-plan et supprime les informations de suivi des modifications antérieures à la période de rétention spécifiée.

    Le processus de nettoyage est un processus en arrière-plan distinct qui utilise la période de rétention spécifiée lorsque vous configurez le suivi des modifications pour la base de données. Le problème est que le processus de nettoyage peut se produire dans le temps entre le moment où la dernière version de synchronisation a été validée et lorsque l’appel à CHANGETABLE(CHANGES...) est effectué. Une dernière version de synchronisation qui était juste valide peut ne plus être valide au moment où les modifications sont obtenues. Par conséquent, des résultats incorrects peuvent être retournés.

  • Les opérations DML en cours se produisent dans les tables Sales et SalesOrders, telles que les opérations suivantes :

    • Les modifications peuvent être apportées aux tables après avoir obtenu la version pour la prochaine fois à l’aide de CHANGE_TRACKING_CURRENT_VERSION(). Par conséquent, plus de modifications peuvent être retournées que prévu.

    • Une transaction peut être validée pendant l'intervalle entre l’appel pour obtenir les modifications de la table Sales et l’appel pour obtenir les modifications de la table SalesOrders. Par conséquent, les résultats de la table SalesOrder peuvent avoir une valeur de clé étrangère qui n’existe pas dans la table Sales.

Pour surmonter les défis répertoriés précédemment, nous vous recommandons d’utiliser l’isolation des instantanés. Cela aide à garantir la cohérence des informations de modification et à éviter les situations de concurrence liées à la tâche de nettoyage en arrière-plan. Si vous n’utilisez pas de transactions d’instantané, le développement d’une application qui utilise le suivi des modifications peut demander significativement plus d'effort.

Utilisation de l’isolation des instantanés

Le suivi des modifications a été conçu pour fonctionner correctement avec l’isolation des instantanés. L’isolation d’instantané doit être activée pour la base de données. Toutes les étapes requises pour obtenir les modifications doivent être incluses dans une transaction d’instantané. Cela garantit que toutes les modifications apportées aux données lors de l’obtention des modifications ne seront pas visibles pour les requêtes à l’intérieur de la transaction d’instantané.

Pour obtenir des données à l’intérieur d’une transaction momentanée, suivez ces étapes :

  1. Réglez le niveau d'isolation des transactions sur "instantané" et démarrez une transaction.

  2. Validez la dernière version de synchronisation à l’aide de CHANGE_TRACKING_MIN_VALID_VERSION().

  3. Obtenez la version à utiliser la prochaine fois à l’aide de CHANGE_TRACKING_CURRENT_VERSION().

  4. Obtenir les modifications de la table Sales à l’aide de CHANGETABLE(CHANGES ...)

  5. Obtenir les modifications de la table Salesorders à l’aide de CHANGETABLE(CHANGES ...)

  6. Validez la transaction.

Certains points à mémoriser, car toutes les étapes pour obtenir des modifications se trouvent dans une transaction d’instantané :

  • Si le nettoyage se produit après la validation de la dernière version de synchronisation, les résultats de CHANGETABLE(CHANGES ...) seront toujours valides, car les opérations de suppression effectuées par le nettoyage ne seront pas visibles à l’intérieur de la transaction.

  • Toutes les modifications apportées à la table Sales ou à la table SalesOrders après l’obtention de la prochaine version de synchronisation ne seront pas visibles, et les appels à CHANGETABLE(CHANGES ...) ne retourneront jamais de modifications avec une version ultérieure à celle retournée par CHANGE_TRACKING_CURRENT_VERSION(). La cohérence entre la table Sales et la table SalesOrders est également conservée, car les transactions qui ont été validées dans le temps entre les appels à CHANGETABLE(CHANGES ...) ne seront pas visibles.

L’exemple suivant montre comment l’isolation d’instantané est activée pour une base de données.

-- The database must be configured to enable snapshot isolation.  
ALTER DATABASE AdventureWorksLT  
    SET ALLOW_SNAPSHOT_ISOLATION ON;  

Une transaction instantanée est utilisée comme suit : Suivez ces étapes :

SET TRANSACTION ISOLATION LEVEL SNAPSHOT;  
BEGIN TRAN  
  -- Verify that version of the previous synchronization is valid.  
  -- Obtain the version to use next time.  
  -- Obtain changes.  
COMMIT TRAN  

Pour plus d'informations sur les transactions instantanées, consultez SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

Alternatives à l’utilisation de l’isolation d’instantané

Il existe des alternatives à l’utilisation de l’isolation des instantanés, mais elles nécessitent davantage de travail pour s’assurer que toutes les exigences de l’application sont remplies. Pour vous assurer que l’last_synchronization_version est valide et que les données ne sont pas supprimées par le processus de nettoyage avant l’obtention des modifications, procédez comme suit :

  1. Vérifiez last_synchronization_version après les appels à CHANGETABLE().

  2. Vérifiez last_synchronization_version dans le cadre de chaque requête pour obtenir des modifications à l’aide de CHANGETABLE().

Les modifications peuvent se produire après l’obtention de la version de synchronisation de l’énumération suivante. Il existe deux façons de gérer cette situation. L’option utilisée dépend de l’application et de la façon dont elle peut gérer les effets secondaires de chaque approche :

  • Ignorez les modifications dont la version est supérieure à la nouvelle version de synchronisation.

    Cette approche a l’effet secondaire qu’une ligne nouvelle ou mise à jour serait ignorée si elle a été créée ou mise à jour avant la nouvelle version de synchronisation, mais ensuite mise à jour. S’il existe une nouvelle ligne, un problème d’intégrité référentielle peut se produire s’il y avait une ligne dans une autre table qui avait été créée et qui faisait référence à la ligne sautée. S’il existe une ligne existante mise à jour, la ligne est ignorée et n’est pas synchronisée jusqu’à la prochaine fois.

  • Incluez toutes les modifications, même celles dont la version est supérieure à la nouvelle version de synchronisation.

    Les lignes dont la version est supérieure à la nouvelle version de synchronisation seront obtenues à nouveau lors de la prochaine synchronisation. Cela doit être attendu et géré par l’application.

En plus des deux options précédentes, vous pouvez concevoir une approche qui combine les deux options, en fonction de l’opération. Par exemple, vous pourriez avoir besoin d'une application pour laquelle il est préférable d'ignorer les modifications de création ou de suppression de ligne qui sont plus récentes que la prochaine version de synchronisation, tandis que les mises à jour de ligne ne sont pas ignorées.

Remarque

Le choix de l’approche qui fonctionnera pour l’application lorsque vous utilisez le suivi des modifications (ou tout mécanisme de suivi personnalisé), nécessite une analyse significative. Par conséquent, il est beaucoup plus simple d’utiliser l’isolation des captures instantanées.

Comment le suivi des modifications gère les modifications apportées à une base de données

Certaines applications qui utilisent le suivi des modifications effectuent une synchronisation bidirectionnelle avec un autre magasin de données. Autrement dit, les modifications apportées dans la base de données SQL Server sont mises à jour dans l’autre magasin de données et les modifications apportées dans l’autre magasin sont mises à jour dans la base de données SQL Server.

Lorsqu’une application met à jour la base de données locale avec des modifications d’un autre magasin de données, l’application doit effectuer les opérations suivantes :

  • Vérifiez les conflits.

    Un conflit se produit lorsque les mêmes données sont modifiées en même temps dans les deux magasins de données. L’application doit être en mesure de vérifier un conflit et d’obtenir suffisamment d’informations pour permettre la résolution du conflit.

  • Stocker les informations de contexte de l’application.

    L’application stocke les données contenant les informations de suivi des modifications. Ces informations seraient disponibles avec d’autres informations de suivi des modifications lorsque des modifications ont été obtenues à partir de la base de données locale. Un exemple courant de ces informations contextuelles est un identificateur du magasin de données qui était la source de la modification.

Pour effectuer les opérations précédentes, une application de synchronisation peut utiliser les fonctions suivantes :

  • CHANGETABLE(VERSION...)

    Lorsqu’une application apporte des modifications, elle peut utiliser cette fonction pour rechercher les conflits. La fonction obtient les dernières informations de suivi des modifications pour une ligne spécifiée dans une table suivie des modifications. Les informations de suivi des modifications incluent la version de la ligne qui a été modifiée pour la dernière fois. Ces informations permettent à une application de déterminer si la ligne a été modifiée après la dernière synchronisation de l’application.

  • WITH CHANGE_TRACKING_CONTEXT

    Une application peut utiliser cette clause pour stocker des données de contexte.

Vérification des conflits

Dans un scénario de synchronisation bidirectionnel, l’application cliente doit déterminer si une ligne n’a pas été mise à jour depuis la dernière fois que l’application a obtenu les modifications.

L’exemple suivant montre comment utiliser la fonction CHANGETABLE(VERSION ...) pour rechercher les conflits de manière la plus efficace, sans requête distincte. Dans l’exemple, CHANGETABLE(VERSION ...) détermine la SYS_CHANGE_VERSION ligne spécifiée par @product id. CHANGETABLE(CHANGES ...) peut obtenir les mêmes informations, mais cela serait moins efficace. Si la valeur de SYS_CHANGE_VERSION la ligne est supérieure à la valeur de @last_sync_version, il existe un conflit. En cas de conflit, la ligne n’est pas mise à jour. La ISNULL() vérification est nécessaire, car il se peut qu'il n'y ait pas d'information de modification disponible pour la ligne. Aucune information de modification n’existe si la ligne n’avait pas été mise à jour depuis l’activation du suivi des modifications ou depuis le nettoyage des informations de modification.

-- Assumption: @last_sync_version has been validated.  
  
UPDATE  
    SalesLT.Product  
SET  
    ListPrice = @new_listprice  
FROM  
    SalesLT.Product AS P  
WHERE  
    ProductID = @product_id AND  
    @last_sync_version >= ISNULL (  
        SELECT CT.SYS_CHANGE_VERSION  
        FROM CHANGETABLE(VERSION SalesLT.Product,  
                        (ProductID), (P.ProductID)) AS CT),  
        0)  

Le code suivant peut vérifier le nombre de lignes mis à jour et identifier plus d’informations sur le conflit.

-- If the change cannot be made, find out more information.  
IF (@@ROWCOUNT = 0)  
BEGIN  
    -- Obtain the complete change information for the row.  
    SELECT  
        CT.SYS_CHANGE_VERSION, CT.SYS_CHANGE_CREATION_VERSION,  
        CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS  
    FROM  
        CHANGETABLE(CHANGES SalesLT.Product, @last_sync_version) AS CT  
    WHERE  
        CT.ProductID = @product_id;  
  
    -- Check CT.SYS_CHANGE_VERSION to verify that it really was a conflict.  
    -- Check CT.SYS_CHANGE_OPERATION to determine the type of conflict:  
    -- update-update or update-delete.  
    -- The row that is specified by @product_id might no longer exist   
    -- if it has been deleted.  
END  

Définition des informations de contexte

À l’aide de la clause WITH CHANGE_TRACKING_CONTEXT, une application peut stocker des informations de contexte avec les informations de modification. Ces informations peuvent ensuite être obtenues à partir de la colonne SYS_CHANGE_CONTEXT retournée par CHANGETABLE(CHANGES ...).

Les informations de contexte sont généralement utilisées pour identifier la source des modifications. Si la source de la modification peut être identifiée, ces informations peuvent être utilisées par un magasin de données pour éviter d’obtenir des modifications lorsqu’elles se synchronisent à nouveau.

  -- Try to update the row and check for a conflict.  
  WITH CHANGE_TRACKING_CONTEXT (@source_id)  
  UPDATE  
     SalesLT.Product  
  SET  
      ListPrice = @new_listprice  
  FROM  
      SalesLT.Product AS P  
  WHERE  
     ProductID = @product_id AND  
     @last_sync_version >= ISNULL (  
         (SELECT CT.SYS_CHANGE_VERSION FROM CHANGETABLE(VERSION SalesLT.Product,  
         (ProductID), (P.ProductID)) AS CT),  
         0)  

Garantir des résultats cohérents et corrects

Une application doit prendre en compte le processus de nettoyage lorsqu’elle valide la valeur de @last_sync_version. Cela est dû au fait que les données ont pu être supprimées après l’appel de CHANGE_TRACKING_MIN_VALID_VERSION(), mais avant la mise à jour.

Important

Nous vous recommandons d’utiliser l’isolation des instantanés et d’apporter les modifications dans une transaction d’instantané.

-- Prerequisite is to ensure ALLOW_SNAPSHOT_ISOLATION is ON for the database.  
  
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;  
BEGIN TRAN  
    -- Verify that last_sync_version is valid.  
    IF (@last_sync_version <  
CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('SalesLT.Product')))  
    BEGIN  
       RAISERROR (N'Last_sync_version too old', 16, -1);  
    END  
    ELSE  
    BEGIN  
        -- Try to update the row.  
        -- Check @@ROWCOUNT and check for a conflict.  
    END  
COMMIT TRAN  

Remarque

Il est possible que la ligne mise à jour dans la transaction d’instantané ait pu être mise à jour dans une autre transaction après le démarrage de la transaction d’instantané. Dans ce cas, un conflit de mise à jour d’isolation d’instantané se produit et entraîne l’arrêt de la transaction. Si cela se produit, réessayez la mise à jour. Cela entraîne ensuite la détection d’un conflit de suivi des modifications et aucune ligne n’est modifiée.

Suivi des modifications et restauration des données

Les applications qui nécessitent une synchronisation doivent prendre en compte le cas dans lequel une base de données avec suivi des modifications activée rétablit une version antérieure des données. Cela peut se produire après la restauration d’une base de données à partir d’une sauvegarde, lorsqu’il existe un basculement vers un miroir de bases de données asynchrone ou lorsqu’il y a un échec lors de l’utilisation de la copie des journaux de transaction. Le scénario suivant illustre le problème :

  1. Le tableau T1 est suivi des modifications et la version minimale valide de la table est 50.

  2. Une application cliente synchronise les données à la version 100 et obtient des informations sur toutes les modifications entre les versions 50 et 100.

  3. Des modifications supplémentaires sont apportées à la table T1 après la version 100.

  4. À la version 120, il y a un échec et l’administrateur de base de données restaure la base de données avec une perte de données. Après l’opération de restauration, la table contient des données jusqu’à la version 70 et la version synchronisée minimale est toujours 50.

    Cela signifie que le magasin de données synchronisé contient des données qui n’existent plus dans le magasin de données principal.

  5. T1 est mis à jour plusieurs fois. La version actuelle est alors 130.

  6. L’application cliente se synchronise à nouveau et fournit une dernière version synchronisée de 100. Le client valide ce nombre correctement, car 100 est supérieur à 50.

    Le client obtient des modifications entre la version 100 et 130. À ce stade, le client n’est pas conscient que les modifications comprises entre 70 et 100 ne sont pas les mêmes qu’auparavant. Les données sur le client et le serveur ne sont pas synchronisées.

Notez que si la base de données a été récupérée à un point après la version 100, il n’y aurait aucun problème avec la synchronisation. Le client et le serveur synchronisent correctement les données pendant l’intervalle de synchronisation suivant.

Le suivi des modifications ne prend pas en charge la récupération après la perte de données. Toutefois, il existe deux options pour détecter ces types de problèmes de synchronisation :

  • Stockez un ID de version de base de données sur le serveur et mettez à jour cette valeur chaque fois qu’une base de données est récupérée ou perd des données. Chaque application cliente stocke l’ID et chaque client doit valider cet ID lorsqu’il synchronise les données. Si la perte de données se produit, les ID ne correspondent pas et les clients réinitialisent. L’un des inconvénients est que si la perte de données n’avait pas franchi la dernière limite synchronisée, le client peut effectuer une réinitialisation inutile.

  • Lorsqu’un client interroge les modifications, enregistrez le dernier numéro de version de synchronisation pour chaque client sur le serveur. En cas de problème avec les données, les derniers numéros de version synchronisés ne correspondent pas. Cela indique qu’une réinitialisation est requise.

Voir aussi

Suivre les modifications de données (SQL Server)
À propos du suivi des modifications (SQL Server)
Gérer le suivi des modifications (SQL Server)
Activer et désactiver le suivi des modifications (SQL Server)
CHANGETABLE (Transact-SQL)
CHANGE_TRACKING_MIN_VALID_VERSION (Transact-SQL)
CHANGE_TRACKING_CURRENT_VERSION (Transact-SQL)
WITH CHANGE_TRACKING_CONTEXT (Transact-SQL)