Delen via


Hoe samenvoegreplicatie conflicten detecteert en oplost

Met samenvoegreplicatie kunnen meerdere knooppunten autonome gegevenswijzigingen aanbrengen, zodat situaties bestaan waarin een wijziging op het ene knooppunt kan conflicteren met een wijziging in dezelfde gegevens op een ander knooppunt. In andere situaties treedt de samenvoegagent een fout op, zoals een schending van een beperking en kan een wijziging die op een bepaald knooppunt is aangebracht, niet doorgeven aan een ander knooppunt. In dit artikel worden typen conflicten beschreven, hoe conflicten worden gedetecteerd en opgelost, en factoren die van invloed zijn op detectie en oplossing.

Conflicten detecteren en oplossen

De Samenvoegagent detecteert conflicten met behulp van de lineage kolom van de MSmerge_contents systeemtabel. Als tracering op kolomniveau is ingeschakeld voor een artikel, wordt de COLV1 kolom ook gebruikt. Deze kolommen bevatten metagegevens over wanneer een rij of kolom wordt ingevoegd of bijgewerkt en over welke knooppunten in een samenvoegreplicatietopologie wijzigingen hebben aangebracht in de rij of kolom. U kunt de sp_showrowreplicainfo systeem opgeslagen procedure gebruiken om deze metagegevens weer te geven.

Wanneer de Merge-agent wijzigingen opsomt die tijdens de synchronisatie moeten worden toegepast, worden de metagegevens voor elke rij bij de Publisher en Subscriber vergeleken. De samenvoegagent gebruikt deze metagegevens om te bepalen of een rij of kolom is gewijzigd op meer dan één knooppunt in de topologie, wat een mogelijk conflict aangeeft. Nadat een conflict is gedetecteerd, start de Samenvoegagent de conflictoplossing die is opgegeven voor het artikel met een conflict en gebruikt de resolver om de conflictwinnaar te bepalen. De winnende rij wordt toegepast bij publisher en abonnee en de gegevens uit de rij die verloren gaan, worden naar een conflicttabel geschreven.

Conflicten worden automatisch en onmiddellijk opgelost door de samenvoegagent, tenzij u interactieve conflictoplossing voor het artikel hebt gekozen. Zie Microsoft Replication Interactive Conflict Resolver voor meer informatie. Als u de winnende rij voor een conflict handmatig wijzigt met behulp van de samenvoegreplicatieconflictviewer, past de samenvoegagent de winnende versie van de rij toe op de verliezende server tijdens de volgende synchronisatie.

Opgeloste conflicten in logboeken

Nadat de samenvoegagent het conflict heeft opgelost op basis van de logica in de conflictoplossing, worden conflictgegevens op basis van het type conflict opgeslagen:

  • Voor UPDATE en INSERT conflicten schrijft het de verloren gegane versie van de rij naar de conflicttabel voor het artikel, die in de vorm conflict_<PublicationName>_<ArticleName> wordt genoemd. De algemene conflictinformatie, zoals het type conflict, wordt naar de tabel MSmerge_conflicts_infogeschreven.

  • Bij DELETE conflicten wordt de verloren versie van de rij naar de MSmerge_conflicts_info tabel geschreven. Wanneer een verwijdering verloren gaat bij een update, zijn er geen gegevens voor de verloren rij (omdat het een verwijderbewerking was), zodat er niets naar conflict_<PublicationName>_<ArticleName>wordt geschreven.

De conflicttabellen voor elk artikel worden gemaakt in de publicatiedatabase, abonnementsdatabase of beide (de standaardinstelling), afhankelijk van de waarde die is opgegeven voor de @conflict_logging parameter van sp_addmergepublication. Elke conflicttabel heeft dezelfde structuur als het artikel waarop deze is gebaseerd, met de toevoeging van de origin_datasource_id kolom. De samenvoegagent verwijdert gegevens uit de conflicttabel als deze ouder is dan de conflictretentieperiode voor de publicatie, die is opgegeven met behulp van de @conflict_retention parameter van sp_addmergepublication (de standaardwaarde is 14 dagen).

Replicatie biedt de replicatieconflictviewer en opgeslagen procedures (sp_helpmergearticleconflicts, sp_helpmergeconflictrowsen sp_helpmergedeleteconflictrows) om conflictgegevens weer te geven. Zie voor meer informatie Conflictoplossing voor samenvoegreplicatie.

Factoren die van invloed zijn op conflictoplossing

Er zijn twee factoren die van invloed zijn op de wijze waarop de samenvoegagent een conflict oplost dat is gedetecteerd:

  • Het type abonnement: client of server (of het abonnement een pull-abonnement is of een push-abonnement heeft geen invloed op conflictoplossing).

  • Het type conflicttracering dat wordt gebruikt: rijniveau, kolomniveau of logisch recordniveau.

Abonnementstypen

Wanneer u een abonnement maakt, geeft u niet alleen op of het een push- of pull-abonnement is, maar ook of het een client- of serverabonnement is; nadat een abonnement is gemaakt, kan het type niet worden gewijzigd (in eerdere versies van SQL Server, client- en serverabonnementen wordt respectievelijk verwezen als lokale en globale abonnementen).

Een abonnement met een toegewezen prioriteitswaarde (van 0.00 tot 99.99) wordt een serverabonnement genoemd; een abonnement met de prioriteitswaarde van De Uitgever wordt een clientabonnement genoemd. Daarnaast kunnen abonnees met serverabonnementen gegevens opnieuw publiceren naar andere abonnees. De volgende tabel bevat een overzicht van de belangrijkste verschillen en het gebruik van elk type abonnee.

Typologie Prioriteitswaarde Gebruikt
Serverapparaat Toegewezen door gebruiker Wanneer u wilt dat verschillende abonnees verschillende prioriteiten hebben.
Cliënt 0.00, maar gegevenswijzigingen nemen aan dat na synchronisatie de prioriteitswaarde van de Uitgever wordt gebruikt. Wanneer u wilt dat alle abonnees dezelfde prioriteit hebben en de eerste abonnee die met de uitgever samenvoegt het conflict wint.

Als een rij wordt gewijzigd in een clientabonnement, wordt er geen prioriteit toegewezen aan de wijziging totdat het abonnement is gesynchroniseerd. Tijdens de synchronisatie krijgen de wijzigingen van de abonnee de prioriteit van de Uitgever toegewezen en behouden ze die prioriteit voor volgende synchronisaties. De uitgever neemt in zekere zin het eigenaarschap van de wijziging aan. Dit gedrag zorgt ervoor dat de eerste subscribent kan synchroniseren met de Publisher om te volgende conflicten met andere subscribenten te winnen voor een bepaalde rij of kolom.

Wanneer u een rij in een serverabonnement wijzigt, wordt de abonnementsprioriteit opgeslagen in de metagegevens voor de wijziging. Deze prioriteitswaarde wordt met de gewijzigde rij meegenomen terwijl deze wordt samengevoegd met wijzigingen bij andere Abonnees. Dit zorgt ervoor dat een wijziging die is aangebracht door een abonnement met een hogere prioriteit, niet verloren gaat bij een volgende wijziging van een abonnement met een lagere prioriteit.

Een abonnement kan geen expliciete prioriteitswaarde hebben die hoger is dan de uitgever. De uitgever van het hoogste niveau in een samenvoegreplicatietopologie heeft altijd een expliciete prioriteitswaarde van 100.00. Alle abonnementen voor die publicatie moeten een prioriteitswaarde hebben die kleiner is dan deze waarde. In een herpublicatietopologie:

  • Als de abonnee gegevens opnieuw publiceert, moet het abonnement een serverabonnement met een prioriteitswaarde kleiner zijn dan de uitgever boven de abonnee.

  • Als de abonnee geen gegevens opnieuw publiceert (omdat deze zich op het bladniveau van de structuur voor opnieuw publiceren bevinden), moet het abonnement een clientabonnement zijn.

Zie Voorbeeld van conflictoplossing voor samenvoeging op basis van abonnementstype en toegewezen prioriteiten voor meer informatie over serverabonnementen en prioriteiten.

Vertraagde conflictmelding

Vertraagde conflictmelding kan optreden bij serverabonnementen met verschillende conflictprioriteiten. Houd rekening met het volgende scenario, waarin niet-conflicterende wijzigingen worden uitgewisseld tussen de uitgever en een abonnee met een lagere prioriteit die tot conflicterende wijzigingen leidt wanneer een abonnee met een hogere prioriteit wordt gesynchroniseerd met de Uitgever:

  1. De uitgever en een abonnee met lage prioriteit, met de naam LowPrioritySub, wisselen wijzigingen uit via verschillende synchronisaties zonder conflict.

  2. Een abonnee met een hogere prioriteit, HighPrioritySub, is enige tijd niet gesynchroniseerd met de uitgever en heeft wijzigingen aangebracht in dezelfde rijen als de LowPrioritySub-abonnee.

  3. De HighPrioritySub Subscriber synchroniseert met de Publisher en wint de conflicten tussen zijn wijzigingen en de LowPrioritySub Subscriber omdat hij een hogere prioriteit heeft dan de LowPrioritySub Subscriber. De uitgever bevat nu de wijzigingen die zijn aangebracht door de HighPrioritySub-abonnee.

  4. De LowPrioritySub Subscriber wordt vervolgens samengevoegd met Publisher en downloadt een groot aantal wijzigingen vanwege de conflicten met de HighPrioritySub Subscriber.

Deze situatie kan problematisch worden wanneer de abonnee met lagere prioriteit wijzigingen heeft aangebracht in dezelfde rijen die nu conflictverliezers zijn. Dit kan leiden tot verlies van alle wijzigingen die door deze abonnee zijn aangebracht. Een mogelijke oplossing voor dit probleem is ervoor te zorgen dat alle abonnees dezelfde prioriteit hebben, tenzij bedrijfslogica anders bepaalt.

Traceringsniveau

Of een gegevenswijziging al dan niet als een conflict in aanmerking komt, is afhankelijk van het type conflicttracking dat u hebt ingesteld voor een artikel: rijniveau, kolomniveau of logisch recordniveau. Zie Advanced Merge Replication Conflict - Resolving in Logical Record voor meer informatie over het bijhouden op logisch record-niveau.

Wanneer conflicten worden herkend op rijniveau, worden wijzigingen in overeenkomende rijen beoordeeld als een conflict, ongeacht of de wijzigingen in dezelfde kolom worden aangebracht. Stel dat er één wijziging wordt aangebracht in de adreskolom van een Publisher-rij en dat er een tweede wijziging wordt aangebracht in de kolom telefoonnummer van de bijbehorende abonneerij (in dezelfde tabel). Bij het bijhouden op rijniveau worden er wijzigingen in dezelfde rij gedetecteerd, waardoor een conflict wordt vastgesteld. Bij het bijhouden op kolomniveau wordt geen conflict gedetecteerd, omdat er wijzigingen zijn aangebracht in verschillende kolommen in dezelfde rij.

Voor het bijhouden van rij- en kolomniveau is de oplossing van het conflict hetzelfde: de hele rij gegevens wordt overschreven door gegevens van de conflictwinnaar (voor het bijhouden van logische records is de oplossing afhankelijk van de artikeleigenschap logical_record_level_conflict_resolution).

De semantiek van de toepassing bepaalt meestal welke traceringsoptie moet worden gebruikt. Als u bijvoorbeeld klantgegevens bijwerkt die doorgaans tegelijkertijd worden ingevoerd, zoals een adres en telefoonnummer, moet het bijhouden op rijniveau worden gekozen. Als bijhouden op kolomniveau in deze situatie is gekozen, worden wijzigingen in het adres van de klant op de ene locatie en het telefoonnummer van de klant op een andere locatie niet gedetecteerd als een conflict: de gegevens worden samengevoegd bij synchronisatie en de fout wordt gemist. In andere situaties is het bijwerken van afzonderlijke kolommen van verschillende sites mogelijk de meest logische keuze. Twee sites hebben bijvoorbeeld toegang tot verschillende soorten statistische informatie op een klant, zoals inkomensniveau en het totale bedrag aan creditcardaankopen. Door het selecteren van tracering op kolomniveau zorgt u ervoor dat beide sites de statistische gegevens voor verschillende kolommen kunnen invoeren zonder onnodige conflicten te genereren.

Opmerking

Als voor uw toepassing geen tracering op kolomniveau is vereist, is het raadzaam om tracering op rijniveau (de standaardinstelling) te gebruiken, omdat dit meestal leidt tot betere synchronisatieprestaties. Als een rijvolgsysteem wordt gebruikt, kan de basistabel maximaal 1.024 kolommen bevatten, maar kolommen moeten uit het artikel gefilterd worden zodat maximaal 246 kolommen worden gepubliceerd. Als kolomtracking wordt gebruikt, kan de basistabel maximaal 246 kolommen bevatten.

Conflicttypen

Hoewel de meeste conflicten betrekking hebben op updates (een update op het ene knooppunt conflicteert met een update of verwijderen op een ander knooppunt), zijn er andere conflicttypen. Elk type conflict dat in deze sectie wordt besproken, kan optreden tijdens de uploadfase of de downloadfase van de samenvoegverwerking. Uploadverwerking is de eerste afstemming van wijzigingen die worden uitgevoerd in een bepaalde samenvoegsessie en is de fase waarin de samenvoegagent wijzigingen repliceert van de abonnee naar de uitgever. Conflicten die tijdens deze verwerking worden gedetecteerd, worden uploadconflicten genoemd. Downloadverwerking omvat het verplaatsen van wijzigingen van publisher naar de abonnee en vindt plaats na het uploaden. Conflicten tijdens deze fase van de verwerking worden downloadconflicten genoemd.

Zie MSmerge_conflicts_info voor meer informatie over conflicttypen, met name de conflict_type en reason_code kolommen.

Update-update-conflicten

De samenvoegagent detecteert update-updateconflicten wanneer een update naar een rij (of kolom of logische record) op het ene knooppunt conflicteert met een andere update naar dezelfde rij op een ander knooppunt. Het gedrag van de standaard resolver in dit geval is het verzenden van de winnende versie van de rij naar het verliezende knooppunt en het vastleggen van de rijversie die verloren gaat in de conflicttabel van het artikel.

Conflicten bijwerken en verwijderen

De samenvoegagent detecteert conflicten bij het verwijderen van updates wanneer een update van gegevens op het ene knooppunt conflicteert met een verwijdering op een ander knooppunt. In dit geval werkt de samenvoegagent een rij bij; Wanneer de samenvoegagent echter naar die rij op de bestemming zoekt, kan de rij niet worden gevonden omdat deze is verwijderd. Als de winnaar het knooppunt is dat de rij heeft bijgewerkt, wordt de verwijdering op het verliesknooppunt verwijderd en verzendt de samenvoegagent de zojuist bijgewerkte rij naar de conflictverliezer. De samenvoegagent registreert informatie over de verliezende versie van de rij in de MSmerge_conflicts_info tabel.

Mislukte wijzigingsconflicten

De samenvoegagent roept deze conflicten op wanneer een bepaalde wijziging niet kan worden toegepast. Dit treedt meestal op vanwege een verschil in beperkingsdefinities tussen de uitgever en abonnee en het gebruik van de NOT FOR REPLICATION eigenschap (NFR) voor de beperking. Voorbeelden zijn:

  • Een conflict met een vreemde sleutel bij de Subscriber, wat kan optreden wanneer de restrictie aan de Subscriber-kant niet is gemarkeerd als NFR.

  • Verschillen in beperkingen tussen publisher en abonnees en de beperkingen worden niet gemarkeerd als NFR.

  • De beschikbaarheid van afhankelijke objecten bij de abonnee is niet beschikbaar. Als u bijvoorbeeld een weergave publiceert, maar niet de tabel waarvan die weergave afhankelijk is, treedt er een fout op als u probeert in te voegen via die weergave bij de abonnee.

  • Join-filterlogica voor een publicatie die niet overeenkomt met de beperkingen van de primaire en vreemde sleutels. Er kunnen conflicten optreden wanneer de relationele SQL Server-engine probeert een beperking te respecteren, maar de samenvoegagent de definitie van het joinfilter tussen de artikelen respecteert. De samenvoegagent kan de wijziging niet toepassen op het doelknooppunt vanwege de beperkingen op tabelniveau, wat tot een conflict leidt.

  • Conflicten vanwege schendingen van unieke indexen of unieke beperkingen of schendingen van primaire sleutels kunnen optreden als er identiteitskolommen zijn gedefinieerd voor het artikel en geautomatiseerd identiteitsbeheer niet wordt gebruikt. Dit kan een probleem zijn als twee abonnees dezelfde identiteitswaarde zouden gebruiken voor een nieuw ingevoegde rij. Zie Identiteitskolommen repliceren voor meer informatie over identiteitsbereikbeheer.

  • Conflicten als gevolg van triggerlogica die voorkomt dat de Merge Agent een rij in de doeltabel invoegt. Overweeg een updatetrigger die is gedefinieerd bij de abonnee; de trigger is niet gemarkeerd als NFR en bevat een ROLLBACK in de logica. Als er een fout optreedt, geeft de trigger een ROLLBACK transactie uit, wat ertoe leidt dat de samenvoegagent een conflict met een mislukte wijziging detecteert.