Comment la réplication de fusion détecte et résout les conflits

La réplication de fusion permet à plusieurs nœuds d'effectuer des changements de données de façon autonome ; c'est pourquoi dans certaines situations un changement apporté sur un nœud peut être en conflit avec les mêmes données situées sur un autre nœud.. Dans d'autres situations, l'Agent de fusion rencontre une erreur telle qu'une violation de contrainte et ne peut pas propager vers un autre nœud un changement effectué sur un nœud particulier. Cette rubrique décrit les types de conflits, comment les conflits sont détectés et résolus, et les facteurs qui affectent la détection et la résolution.

Détection et résolution des conflits

L'Agent de fusion détecte les conflits à l'aide de la colonne lineage de la table système MSmerge_contents ; si le suivi au niveau de la colonne est activé pour un article, la colonne COLV1 est également utilisée. Ces colonnes contiennent des métadonnées indiquant quand une ligne ou une colonne sont insérées ou mises à jour, et quels nœuds, dans une topologie de réplication de fusion, ont apporté des changements à la ligne ou la colonne. Vous pouvez utiliser la procédure stockée système sp_showrowreplicainfo (Transact-SQL) pour afficher ces métadonnées.

Lorsque l'Agent de fusion énumère les changements à appliquer durant la synchronisation, il compare les métadonnées de chaque ligne sur le serveur de publication et sur l'Abonné. L'Agent de fusion utilise ces métadonnées pour déterminer si une ligne ou une colonne a changé dans plus d'un nœud de la topologie, ce qui indique un conflit potentiel. Après détection d'un conflit, l'Agent de fusion démarre l'outil de résolution de conflit spécifié pour l'article en conflit, et utilise cet outil pour déterminer qui remporte le conflit. La ligne gagnante est appliquée sur le serveur de publication et l'Abonné, et les données de la ligne perdante sont écrites dans une table de conflits.

Les conflits sont résolus automatiquement et immédiatement par l'Agent de fusion, sauf si vous avez choisi la résolution de conflit interactive pour cet article. Pour plus d'informations, consultez Résolution interactive des conflits. Si vous changez manuellement la ligne gagnante d'un conflit à l'aide de l'outil de résolution des conflits de réplication de fusion, l'Agent de fusion appliquera la version gagnante de la ligne sur le serveur lors de la synchronisation suivante.

Journalisation des conflits résolus

Après résolution du conflit par l'Agent de fusion conformément à la logique de l'outil de résolution de conflit, l'Agent consigne les données du conflit en fonction du type de conflit :

  • Pour les conflits UPDATE et INSERT, il écrit la version perdante de la ligne dans la table de conflits de l'article, dont le nom a la forme conflict_<PublicationName>_<ArticleName>. Les informations générales de conflit, telles que le type de conflit, sont écrites dans la table MSmerge_conflicts_info.

  • Pour les conflits DELETE, il écrit la version perdante de la ligne dans la table MSmerge_conflicts_info. Lorsqu'une suppression perd contre une mise à jour, il n'y a pas de données pour la ligne perdante (parce que c'était une suppression), et rien n'est écrit dans la table conflict_<PublicationName>_<ArticleName>.

Les tables de conflits de chaque article sont créées dans la base de données de publication, la base de données d'abonnement ou les deux (par défaut), selon la valeur spécifiée pour le paramètre @conflict_logging de sp_addmergepublication. Chaque table de conflits a la même structure que l'article sur lequel elle est basée, plus une colonne origin_datasource_id. L'Agent de fusion supprime les données de la table de conflits si elles sont plus anciennes que la période de rétention de conflit pour la publication, qui est spécifiée à l'aide du paramètre @conflict_retention de sp_addmergepublication (par défaut, 14 jours).

La réplication fournit l'outil de résolution des conflits de réplication et des procédures stockées (sp_helpmergearticleconflicts, sp_helpmergeconflictrows et sp_helpmergedeleteconflictrows) pour afficher les données de conflit. Pour plus d'informations, consultez Procédure : afficher et résoudre les conflits de données pour les publications de fusion (SQL Server Management Studio) et Procédure : afficher les informations relatives aux conflits pour les publications de fusion (programmation Transact-SQL de la réplication).

Facteurs affectant la résolution de conflit

Deux facteurs affectent la façon dont l'Agent de fusion résout un conflit qu'il a détecté :

  • Type d'abonnement : client ou serveur (que l'abonnement s'effectue par envoi ou par extraction de données, la résolution de conflit n'est pas affectée).

  • Le type de suivi de conflit utilisé : au niveau de la ligne, de la colonne ou de l'enregistrement logique.

Types d'abonnements

Lorsque vous créez un abonnement, vous devez non seulement spécifier si c'est un abonnement par envoi ou par extraction de données, mais également si c'est un abonnement client ou serveur ; après la création d'un abonnement, son type ne peut plus être changé (dans les versions précédentes de MicrosoftSQL Server, les abonnements client et serveur étaient appelés, respectivement, abonnements local et global).

Un abonnement doté d'une valeur de priorité affectée (de 0,00 à 99,99) s'appelle un abonnement serveur ; un abonnement utilisant la valeur de priorité du serveur de publication s'appelle un abonnement client. De plus, les Abonnés à des abonnements serveurs peuvent republier les données vers d'autres Abonnés. Le tableau suivant récapitule les principales différences et utilisations liées à chaque type d'Abonné.

Type

Valeur de priorité

Utilisé

Serveur

Affectée par l'utilisateur

Lorsque vous souhaitez que les différents Abonnés possèdent des priorités différentes.

Client

0,00, mais les changements de données endossent la valeur de priorité du serveur de publication après la synchronisation

Lorsque vous souhaitez que tous les Abonnés possèdent la même priorité, et que le premier Abonné à fusionner avec le serveur de publication gagne le conflit.

Si une ligne est modifiée dans un abonnement client, aucune priorité n'est affectée à la modification jusqu'à ce que l'abonnement soit synchronisé. Durant la synchronisation, les modifications en provenance de l'Abonné reçoivent la priorité du serveur de publication et conservent cette priorité pour les synchronisations suivantes. Dans un sens, le serveur de publication est propriétaire de la modification. Ce comportement permet au premier Abonné de se synchroniser avec le serveur de publication pour gagner les conflits ultérieurs avec les autres Abonnés à propos d'une ligne ou d'une colonne données.

Lorsque vous modifiez une ligne dans un abonnement serveur, la priorité d'abonnement est stockée dans les métadonnées pour cette modification. Cette valeur de priorité suit la ligne modifiée lorsqu'elle fusionne avec les modifications des autres Abonnés. Cela permet de garantir qu'une modification effectuée par un abonnement de priorité supérieure ne risque pas de perdre face à une modification ultérieure effectuée par un abonnement de priorité inférieure.

Un abonnement ne peut pas avoir une valeur de priorité explicite qui soit supérieure à celle de son serveur de publication. Le serveur de publication de niveau supérieur dans une topologie de réplication de fusion a toujours une valeur de priorité explicite de 100,00. Tous les abonnements à cette publication doivent avoir une valeur de priorité inférieure. Dans une topologie de republication :

  • Si l'Abonné republie les données, l'abonnement doit être un abonnement serveur avec une valeur de priorité inférieure à celle du serveur de publication mais supérieure à l'Abonné.

  • Si l'Abonné ne republie pas les données (parce qu'il se situe au niveau feuille de l'arborescence de republication), l'abonnement doit être un abonnement client .

Pour plus d'informations sur les abonnements serveurs et les priorités, consultez Exemple d'une résolution de conflit de fusion d'après le type d'abonnement et les priorités affectées.

Notification de conflit différée

Une notification de conflit différée peut se produire avec les abonnements serveurs qui ont des priorités de conflit différentes. Soit le scénario ci-dessous, dans lequel des modifications non conflictuelles sont échangées entre le serveur de publication et un Abonné de faible priorité, qui produisent des conflits de modifications lorsqu'un Abonné de priorité supérieure se synchronise avec le serveur de publication :

  1. Le serveur de publication et un Abonné de faible priorité, nommé LowPrioritySub, échangent des modifications sur plusieurs synchronisations sans conflit.

  2. Un Abonné de priorité supérieure, nommé HighPrioritySub, ne s'est pas synchronisé avec le serveur de publication dans un certain délai, et a effectué des modifications sur les mêmes lignes que l'Abonné LowPrioritySub.

  3. L'Abonné HighPrioritySub se synchronise avec le serveur de publication et remporte les conflits entre ses modifications et celles de l'Abonné LowPrioritySub, puisqu'il a une priorité supérieure. Le serveur de publication contient maintenant les modifications effectuées par l'Abonné HighPrioritySub.

  4. L'Abonné LowPrioritySub fusionne alors avec le serveur de publication et télécharge un grand nombre de modifications dues aux conflits avec l'Abonné HighPrioritySub.

Cette situation peut devenir problématique si l'Abonné LowPrioritySub a effectué dans les mêmes lignes des modifications qui maintenant ont perdu le conflit. Il en résulte la perte de toutes les modifications apportées par cet Abonné non prioritaire. Une solution possible de ce problème serait de donner la même priorité à tous les Abonnés, sauf si la logique métier en décide autrement.

Niveau de suivi

Qu'une modification de données provoque ou non un conflit dépend du type de suivi de conflit que vous définissez pour un article : au niveau de la ligne, de la colonne ou de l'enregistrement logique. Pour plus d'informations sur le suivi au niveau de l'enregistrement logique, consultez Détection et résolution des conflits dans les enregistrements logiques.

Lorsque les conflits sont reconnus au niveau de la ligne, les modifications apportées aux lignes correspondantes sont considérées comme un conflit, que ces modifications soient apportées ou non à la même colonne. Par exemple, supposons qu'une modification est apportée à la colonne des adresses d'une ligne du serveur de publication, et qu'une deuxième modification est apportée à la colonne des numéros de téléphone de la ligne correspondante d'un Abonné (dans la même table). Avec le suivi au niveau de la ligne, un conflit est détecté, car des modifications ont été apportées à la même ligne. Avec le suivi au niveau de la colonne, aucun conflit n'est détecté, car les modifications ont été apportées dans des colonnes différentes de la même ligne.

Pour le suivi au niveau de la ligne ou de la colonne, la résolution du conflit est identique : toute la ligne de données est écrasée par les données du vainqueur du conflit (pour le suivi au niveau de l'enregistrement logique, la résolution dépend de la propriété logical_record_level_conflict_resolution de l'article).

La sémantique de l'application détermine généralement l'option de surveillance à utiliser. Par exemple, si vous mettez à jour des données se rapportant à des clients, qui sont généralement entrées en même temps, par exemple l'adresse et le numéro de téléphone, choisissez l'option de surveillance des lignes. Si dans cette situation vous choisissez la surveillance des colonnes, les modifications de l'adresse du client à un emplacement et du numéro de téléphone du client à un autre emplacement ne sont pas détectées comme un conflit. Les données sont fusionnées lors de la synchronisation et l'erreur passe inaperçue. Dans d'autres situations, la mise à jour de colonnes individuelles à partir de différents sites peut représenter le choix le plus logique. Par exemple, deux sites peuvent avoir accès à différents types d'informations statistiques sur un client, le niveau des revenus et le total en francs d'achats par carte de crédit. La surveillance des colonnes permet de garantir que les deux sites peuvent entrer des données statistiques dans les différentes colonnes, sans provoquer de conflits inutiles.

[!REMARQUE]

Si votre application ne nécessite par le suivi au niveau de la colonne, il vous est conseillé d'utiliser le suivi au niveau de la ligne (option par défaut) parce qu'elle produit en général de meilleures performances de synchronisation. En cas d'utilisation du suivi de lignes, la table de base peut contenir jusqu'à 1 024 colonnes au maximum, mais elles doivent être filtrées au niveau de l'article, afin que 246 colonnes au maximum soient publiées. Si la fonction de suivi de colonnes est utilisée, la table de base peut inclure 246 colonnes au maximum.

Types de conflits

Bien que la majorité des conflits soient liés aux mises à jour (une mise à jour sur un nœud entre en conflit avec une mise à jour ou une suppression sur un autre nœud), il existe d'autres types de conflits. Chaque type de conflit abordé dans cette section peut se produire durant la phase de téléchargement (vers le client ou le serveur) du traitement de fusion. Le téléchargement vers le serveur constitue la première réconciliation des modifications effectuées lors d'une session de fusion particulière ; c'est la phase durant laquelle l'Agent de fusion réplique les modifications de l'Abonné vers le serveur de publication. Les conflits détectés durant ce traitement sont appelés conflits de téléchargement vers le serveur. Le téléchargement vers l'Abonné transfère les modifications du serveur de publication vers l'Abonné, et se produit après le téléchargement vers le serveur. Les conflits détectés durant ce traitement sont appelés conflits de téléchargement vers l'Abonné.

Pour plus d'informations sur les types de conflits, consultez surtout les colonnes conflict_type et reason_code dans MSmerge_conflicts_info (Transact-SQL).

Conflits mise à jour-mise à jour

L'Agent de fusion détecte les conflits mise à jour-mise à jour lorsqu'une mise à jour sur une ligne (ou colonne, ou enregistrement logique) dans un nœud entre en conflit avec une autre mise à jour sur la même ligne dans un autre nœud. Dans ce cas, l'outil de résolution par défaut envoie la version gagnante de la ligne vers le nœud perdant et journalise la version de ligne perdante dans la table de conflits de l'article.

Conflits mise à jour-suppression

L'Agent de fusion détecte les conflits mise à jour-suppression lorsqu'une mise à jour de données dans un nœud entre en conflit avec une suppression dans un autre nœud. Dans ce cas, l'Agent de fusion met à jour une ligne ; cependant, quand il cherche cette ligne sur le nœud de destination, il ne la trouve pas puisqu'elle a été supprimée. Si le gagnant est le nœud qui a mis à jour la ligne, la suppression sur le nœud perdant est annulée et l'Agent de fusion envoie la ligne nouvellement mise à jour au perdant du conflit. L'Agent de fusion journalise les informations concernant la version perdante de la ligne dans la table MSmerge_conflicts_info.

Conflits d'échec de modification

L'Agent de fusion soulève ces conflits lorsqu'il ne peut pas appliquer un changement particulier. Ceci se produit en général en raison d'une différence dans les définitions de contraintes du serveur de publication et de l'Abonné, et de l'utilisation de la propriété NOT FOR REPLICATION (NFR) sur la contrainte. Les exemples comprennent :

  • Un conflit de clé étrangère au niveau de l'Abonné, qui peut se produire lorsque la contrainte côté-Abonné n'est pas marquée comme NFR.

  • Des différences dans les contraintes entre le serveur de publication et les Abonnés, si les contraintes ne sont pas marquées comme NFR.

  • Indisponibilité d'objets dépendants au niveau de l'Abonné. Par exemple, si vous publiez une vue, mais pas la table dont dépend cette vue, un échec se produit si vous tentez une insertion via cette vue au niveau de l'Abonné.

  • Logique de filtres de jointure pour une publication qui ne respecte pas les contraintes de clé primaire et de clé étrangère. Des conflits peuvent se produire si le moteur relationnel de SQL Server tente d'honorer une contrainte pendant que l'Agent de fusion honore la définition de filtres de jointure entre les articles. L'Agent de fusion ne peut pas appliquer la modification au niveau du nœud de destination en raison des contraintes sur les tables, ce qui provoque un conflit.

  • Des conflits dus à des violations d'index unique ou de contrainte unique ou à des violations de clé primaire peuvent se produire si des colonnes d'identité sont définies pour l'article, et si la gestion automatique des identités n'est pas utilisée. Ceci peut être un problème si deux Abonnés sont amenés à utiliser la même valeur d'identité pour une ligne nouvellement insérée. Pour plus d'informations sur la gestion des plages d'identité, consultez Réplication de colonnes d'identité.

  • Conflits dus à une logique de déclencheur empêchant l'Agent de fusion d'insérer une ligne dans la table de destination. Soit par exemple un déclencheur de mise à jour défini sur l'Abonné ; ce déclencheur n'est pas marqué comme NFR et comporte un ROLLBACK dans sa logique. Si un échec se produit, le déclencheur émet un ROLLBACK de la transaction, et l'Agent de fusion détecte un conflit d'échec de modification.