Konflikterkennung und -lösung bei der Mergereplikation

Die Mergereplikation lässt autonome Datenänderungen durch Knoten zu, sodass es zu Konflikten kommen kann, wenn dieselben Daten an mehreren Knoten unterschiedlich geändert werden. Es gibt auch Situationen, in denen der Merge-Agent Fehler feststellt, wie z. B. eine Einschränkungsverletzung, und daher eine an einem bestimmten Knoten vorgenommene Änderung nicht an andere Knoten weiterleiten kann. In diesem Thema werden mögliche Konflikttypen behandelt, und es wird beschrieben, wie Konflikte erkannt und gelöst werden und welche Faktoren die Konflikterkennung und -lösung beeinflussen.

Erkennen und Lösen von Konflikten

Der Merge-Agent verwendet die lineage-Spalte der MSmerge_contents-Systemtabelle, um Konflikte zu erkennen. Wenn die Nachverfolgung auf Spaltenebene für einen Artikel aktiviert ist, wird auch die COLV1-Spalte. Diese Spalten enthalten Metadaten, in denen aufgezeichnet wird, wann Zeilen oder Spalten eingefügt oder aktualisiert werden und welche Knoten der Mergereplikationstopologie die Änderungen vorgenommen haben. Verwenden Sie die systemgespeicherte Prozedur sp_showrowreplicainfo (Transact-SQL), um diese Metadaten anzuzeigen.

Der Merge-Agent sammelt die während der Synchronisierung anzuwendenden Änderungen und vergleicht unterdessen die Metadaten jeder Zeile am Verleger und Abonnenten. Der Merge-Agent verwendet die Metadaten also, um zu ermitteln, ob Zeilen oder Spalten an verschiedenen Knoten in der Topologie geändert wurden, wobei möglicherweise Konflikte verursacht wurden. Wurde ein solcher Konflikt erkannt, startet der Merge-Agent den für den problematischen Artikel angegebenen Konfliktlöser und verwendet diesen, um den Konfliktgewinner zu bestimmen. Die gewinnende Zeile wird auf den Verleger und den Abonnenten angewendet, während die verlierende Zeile in eine Konflikttabelle geschrieben wird.

Der Merge-Agent löst Konflikte automatisch und unmittelbar, es sei denn, Sie haben die interaktive Konfliktlösung für den Artikel ausgewählt. Weitere Informationen finden Sie unter Interaktive Konfliktlösung. Wenn Sie die gewinnende Zeile eines Konflikts im Replikationskonflikt-Viewer manuell ändern, wendet der Merge-Agent die gewinnende Version der Zeile während der nächsten Synchronisierung auf den verlierenden Server an.

Protokollieren von gelösten Konflikten

Wenn der Merge-Agent einen Konflikt gemäß der Logik des Konfliktlösers gelöst hat, protokolliert er die dem Konflikttyp entsprechenden Konfliktdaten:

  • Bei UPDATE- und INSERT-Konflikten wird die verlierende Version der Zeile in die Konflikttabelle des Artikels geschrieben, deren Name folgendermaßen gebildet wird: conflict_<PublicationName>_<ArticleName>. Die allgemeinen Konfliktinformationen, wie z. B. der Konflikttyp, werden in die MSmerge_conflicts_info-Tabelle geschrieben.

  • Bei DELETE-Konflikten wird die verlierende Version der Zeile in die MSmerge_conflicts_info-Tabelle geschrieben. Wenn einen DELETE-Anweisung gegen einen UPDATE-Anweisung verliert, gibt es keine Daten für die verlierende Zeile (da es sich um ein DELETE handelt). Infolgedessen wird nichts in die conflict_<PublicationName>_<ArticleName>-Tabelle geschrieben.

Die Konflikttabellen der Artikel werden in der Veröffentlichungs- oder in der Abonnementdatenbank, standardmäßig jedoch in beiden erstellt, je nachdem, welcher Wert für den @conflict_logging-Parameter der sp_addmergepublication-Prozedur angegeben wurde. Konflikttabellen weisen dieselbe Struktur auf wie die Artikel, auf denen sie basieren, enthalten jedoch zusätzlich eine origin_datasource_id-Spalte. Der Merge-Agent löscht die Daten aus der Konflikttabelle, wenn diese älter sind als die durch den @conflict_retention-Parameter der sp_addmergepublication-Prozedur angegebene Konfliktbeibehaltungsdauer der Veröffentlichung. Der Standardwert beträgt 14 Tage.

Zur Anzeige von Konfliktdaten verfügt die Replikation über einen Replikationskonflikt-Viewer sowie verschiedene gespeicherte Prozeduren (sp_helpmergearticleconflicts, sp_helpmergeconflictrows und sp_helpmergedeleteconflictrows). Weitere Informationen finden Sie unter Vorgehensweise: Anzeigen und Lösen von Datenkonflikten für Mergeveröffentlichungen (SQL Server Management Studio) und Vorgehensweise: Anzeigen von Konfliktinformationen zu Mergeveröffentlichungen (Replikationsprogrammierung mit Transact-SQL).

Faktoren, die sich auf die Konfliktlösung auswirken

Zwei Faktoren beeinflussen die Art und Weise, wie der Merge-Agent erkannte Konflikte löst:

  • Der Abonnementtyp: Client oder Server (ob es sich um ein Pull- oder ein Pushabonnement handelt, hat keinen Einfluss auf die Konfliktlösung).

  • Der verwendete Typ der Konfliktnachverfolgung: Nachverfolgung auf Zeilenebene, auf Spaltenebene, oder auf der Ebene des logischen Datensatzes.

Abonnementtypen

Beim Erstellen eines Abonnements geben Sie an, ob es sich um ein Push- oder ein Pullabonnement, ein Client- oder ein Serverabonnement (in früheren Versionen von Microsoft SQL Server als lokales bzw. globales Abonnement bezeichnet) handeln soll. Wenn das Abonnement einmal erstellt ist, können Sie den Typ nicht mehr ändern.

Ein Abonnement mit einem zugewiesenen Priority-Wert (von 0,00 bis 99,99) wird als Serverabonnement bezeichnet; ein Abonnement, das den Priority-Wert des Verlegers verwendet, wird als Clientabonnement bezeichnet. Abonnenten, die über ein Serverabonnement verfügen, können selbst Daten auf anderen Abonnenten veröffentlichen. In der folgenden Tabelle werden die Hauptunterschiede und Verwendungsweisen der einzelnen Abonnententypen zusammengefasst.

Typ

Priority-Wert

Verwendungsweise

Server

Vom Benutzer zugewiesen

Verschiedene Abonnenten sollen unterschiedliche Prioritäten erhalten.

Client

0,00, Datenänderungen nehmen jedoch nach der Synchronisierung den Priority-Wert des Verlegers an.

Alle Abonnenten sollen dieselbe Priorität erhalten; der erste Abonnent, der mit dem Verleger zusammengeführt wird, gewinnt den Konflikt.

Wird eine Zeile in einem Clientabonnement geändert, wird der Änderung erst dann eine Priorität zugewiesen, wenn das Abonnement synchronisiert wird. Während der Synchronisierung werden den Änderungen des Abonnenten die Priorität des Verlegers zugewiesen und behalten diese Priorität bei späteren Synchronisierungen bei. In gewisser Weise nimmt der Verleger die Urheberschaft der Änderung an. Diese Verhaltensweise ermöglicht dem ersten Abonnenten das Synchronisieren mit dem Verleger sowie den Gewinn bei späteren Zeilen- oder Spaltenänderungskonflikten mit anderen Abonnenten.

Wenn Sie eine Zeile in einem Serverabonnement ändern, wird die Abonnementpriorität für die Änderung in den Metadaten gespeichert. Dieser Priority-Wert wird mit der geänderten Zeile während der Zusammenführung mit Änderungen auf anderen Abonnenten übertragen. Dadurch wird sichergestellt, dass eine Änderung durch ein Abonnement höherer Priorität nicht gegen eine spätere Änderung durch ein Abonnement niedrigerer Priorität verliert.

Ein Abonnement darf keinen expliziten höheren Priority-Wert als sein Verleger besitzen. In einer Mergereplikationstopologie besitzt der Verleger der obersten Ebene immer einen expliziten Priority-Wert von 100,00. Alle Abonnenten der Veröffentlichung müssen eine niedrigere Priorität aufweisen. In einer Wiederveröffentlichungstopologie:

  • Wenn der Abonnent Daten neu veröffentlicht, muss das Abonnement vom Typ Server sein und einen niedrigeren Priority-Wert als der Verleger über dem Abonnenten besitzen.

  • Wenn der Abonnent keine Daten neu veröffentlicht (weil er sich auf der Blattebene der Wiederveröffentlichungsstruktur befindet), muss das Abonnement vom Typ Client sein.

Weitere Informationen zu Serverabonnements finden Sie unter Beispiel für die Lösung von Mergekonflikten auf der Basis des Abonnementtyps und der zugewiesenen Prioritäten.

Verzögerte Konfliktbenachrichtigung

Die Konfliktbenachrichtigung kann zeitlich verzögert werden, wenn Serverabonnements verschiedene Konfliktprioritäten besitzen. Das folgende Szenario soll veranschaulichen, wie konfliktlose Änderungen zwischen dem Verleger und einem Abonnenten mit niedrigerer Priorität ausgetauscht werden, und daraufhin Änderungskonflikte hervorheben, sobald ein Abonnent mir höherer Priorität mit dem Verleger synchronisiert wird:

  1. Der Verleger und ein Abonnent namens LowPrioritySub tauschen über mehrere Synchronisierungen konfliktlos Änderungen aus.

  2. Ein Abonnent mit höherer Priorität namens HighPrioritySub wurde seit geraumer Zeit nicht mit dem Verleger synchronisiert, hat jedoch Änderungen an denselben Zeilen vorgenommen wie der LowPrioritySub-Abonnent.

  3. Der HighPrioritySub-Abonnent wird nun mit dem Verleger synchronisiert und gewinnt bei den Konflikten zwischen seinen Änderungen und denen des LowPrioritySub-Abonnenten, da er eine höhere Priorität besitzt. Der Verleger enthält jetzt die von dem HighPrioritySub-Abonnenten vorgenommenen Änderungen.

  4. Der LowPrioritySub-Abonnent wird jetzt mit dem Verleger zusammengeführt und heruntergeladen aufgrund der Konflikte mit dem HighPrioritySub-Abonnenten zahlreiche Änderungen.

Dieser Umstand wird dann problematisch, wenn der Abonnent mit der niedrigeren Priorität Änderungen an denselben Zeilen vorgenommen hat wie derjenige mit der höheren Priorität und nun bei den Konflikten verliert, da in diesem Fall alle Änderungen dieses Abonnenten verloren werden. Eine Lösungsmöglichkeit für dieses Problem besteht darin, allen Abonnenten dieselbe Priorität zuzuweisen, es sei denn, die Geschäftslogik steht dem entgegen.

Nachverfolgungsebene

Ob eine Datenänderung als Konflikt eingestuft wird, ist von dem Konfliktnachverfolgungstyp abhängig, den Sie für die einzelnen Artikel festlegen: Zeilenebene, Spaltenebene oder logische Datensätze. Weitere Informationen zur Nachverfolgung auf der Ebene des logischen Datensatzes finden Sie unter Ermitteln und Lösen von Konflikten in logischen Datensätzen.

Wenn Konflikte auf der Zeilenebene erkannt werden, werden Änderungen an den entsprechenden Zeilen als Konflikt eingestuft, unabhängig davon, ob die Änderungen an derselben Spalte vorgenommen werden. Nehmen Sie beispielsweise an, es wird eine Änderung an der address-Spalte einer Zeile auf dem Verleger und eine zweite Änderung an der phone number-Spalte (in derselben Tabelle) in der entsprechenden Zeile auf dem Abonnenten vorgenommen. Bei der Nachverfolgung auf Zeilenebene wird ein Konflikt erkannt, da Änderungen an derselben Zeile vorgenommen wurden. Bei der Nachverfolgung auf Spaltenebene wird kein Konflikt erkannt, da Änderungen zwar an derselben Zeile, jedoch in verschiedenen Spalten vorgenommen wurden.

Bei der Nachverfolgung auf Zeilenebene wie auch auf Spaltenebene ist die Konfliktlösung dieselbe: die gesamte Zeile wird mit den Daten des Konfliktgewinners überschrieben. Bei der Nachverfolgung auf der Ebene des logischen Datensatzes ist die Konfliktlösung von der Artikeleigenschaft logical_record_level_conflict_resolution abhängig.

Die Anwendungssemantik bestimmt in der Regel, welche Nachverfolgungsoption verwendet werden soll. Wenn Sie z. B. Kundendaten aktualisieren, die in der Regel gleichzeitig eingegeben werden, wie beispielsweise Adresse und Telefonnummer, empfiehlt es sich, die Nachverfolgung auf Zeilenebene auszuwählen. Wird in dieser Situation die Nachverfolgung auf Spaltenebene ausgewählt, werden Änderungen der Kundenadresse an einem Standort und der Kundentelefonnummer am anderen Standort nicht als Konflikt erkannt. Die Daten werden bei der Synchronisierung zusammengeführt, und der Fehler wird übersehen. In anderen Situationen kann sich das Aktualisieren einzelner Spalten von verschiedenen Standorten als logischste Wahl erweisen. Zwei Standorte haben z. B. Zugriff auf verschiedene Typen von statistischen Informationen zu einem Kunden, wie z. B. Höhe des Einkommens und Gesamtbetrag der Kreditkartenkäufe. Durch das Auswählen der Nachverfolgung auf Spaltenebene wird sichergestellt, dass an beiden Standorten statistische Daten für verschiedene Spalten eingegeben werden können, ohne unnötige Konflikte zu generieren.

HinweisHinweis

Wenn für Ihre Anwendung die Nachverfolgung auf Spaltenebene nicht erforderlich ist, empfiehlt es sich, die Standardeinstellung Nachverfolgung auf Zeilenebene zu verwenden, da diese in der Regel eine höhere Synchronisierungsleistung erzielt. Wenn das Protokollieren auf Zeilenebene verwendet wird, darf die Basistabelle maximal 1.024 Spalten enthalten. Aus den Spalten muss jedoch der Artikel gefiltert werden, sodass maximal 246 Spalten veröffentlicht werden. Wenn das Protokollieren auf Spaltenebene verwendet wird, darf die Basistabelle maximal 246 Spalten enthalten.

Konflikttyp

Die meisten Konflikte entstehen in Zusammenhang mit UPDATES (ein UPDATE auf einem Knoten gerät in Konflikt mit einem UPDATE oder DELETE auf einem anderen Knoten). Es gibt jedoch auch andere Konflikttypen. Jeder der in diesem Abschnitt behandelten Konflikttypen kann während der Upload- oder Downloadphase der Mergeverarbeitung auftreten. Bei der Uploadverarbeitung einer Mergesitzung findet der erste Vergleich der Änderungen statt. In dieser Phase repliziert der Merge-Agent die Änderungen des Abonnenten und überträgt sie auf den Verleger. Konflikte, die während dieser Phase erkannt werden, werden als Uploadkonflikte bezeichnet. Bei der Downloadverarbeitung werden Änderungen vom Verleger an den Abonnenten übertragen. Diese Phase findet nach der Uploadverarbeitung statt. Konflikte, die während dieser Phase erkannt werden, werden als Downloadkonflikte bezeichnet.

Weitere Informationen zu Konflikttypen finden Sie unter MSmerge_conflicts_info (Transact-SQL), insbesondere in der conflict_type-Spalte und der reason_code-Spalte.

UPDATE/UPDATE-Konflikte

Der Merge-Agent erkennt UPDATE/UPDATE-Konflikte, wenn eine UPDATE-Anweisung für eine Zeile, bzw. Spalte, oder für einen logischen Datensatz auf einem Knoten mit einem anderen UPDATE für dieselbe Zeile auf einem anderen Knoten in Konflikt steht. In diesem Fall sendet der Standardkonfliktlöser die gewinnende Version der Zeile an den verlierenden Knoten und protokolliert die Version der verlierenden Zeile in der Konflikttabelle des Artikels.

UPDATE/DELETE-Konflikte

Der Merge-Agent erkennt UPDATE/DELETE-Konflikte, wenn aktualisierte Daten auf einem Knoten mit gelöschten Daten auf einem anderen in Konflikt stehen. In diesem Fall aktualisiert der Merge-Agent zunächst die eine Zeile; wenn er jedoch am Zielort nach dieser Zeile sucht, kann er sie nicht finden, da sie gelöscht wurde. Ist der Gewinner der Knoten, der die Zeile aktualisiert hat, wird das Löschen der Zeile auf dem verlierenden Knoten ignoriert und die aktualisierte Zeile an den Verlierer gesendet. Der Merge-Agent protokolliert die Informationen zu der verlierenden Version der Zeile in der MSmerge_conflicts_info-Tabelle.

fehlerhafte Änderungskonflikte

Der Merge-Agent löst diese Konflikte aus, wenn bestimmte Änderungen nicht angewendet werden können. In der Regel tritt dies aufgrund von Unterschieden in den Einschränkungsdefinitionen des Verlegers und des Abonnenten sowie der Verwendung der Eigenschaft NOT FOR REPLICATION (NFR) mit der Einschränkung auf. Beispiele:

  • Ein Fremdschlüsselkonflikt auf dem Abonnenten kann auftreten, wenn die Einschränkung seitens des Abonnenten nicht als NFR gekennzeichnet ist.

  • Unterschiede in den Einschränkungen zwischen Verleger und Abonnenten, wenn die Eigenschaften nicht als NFR gekennzeichnet sind.

  • Nichtverfügbarkeit von abhängigen Objekten beim Abonnenten. Wenn Sie beispielsweise eine Sicht veröffentlichen, die der Sicht zugrunde liegende Tabelle jedoch nicht, tritt ein Fehler auf, wenn Sie versuchen, beim Abonnenten über diese Sicht eine INSERT-Anweisung durchzuführen.

  • Verknüpfungsfilterlogik bei einer Veröffentlichung ohne Übereinstimmung des Primärschlüssels und der Fremdschlüsseleinschränkungen. Konflikte können auftreten, wenn das relationale SQL Server-Datenbankmodul versucht, eine Einschränkung zu berücksichtigen, der Merge-Agent jedoch die Verknüpfungsfilterdefinition zwischen den Artikeln berücksichtigt. Der Merge-Agent kann dann die Änderung aufgrund der Einschränkungen auf Tabellenebene nicht auf dem Zielknoten anwenden, sodass ein Konflikt entsteht.

  • Konflikte aufgrund von Verletzungen des eindeutigen Indexes, eindeutiger Einschränkungen oder des Primärschlüssels können auftreten, wenn Identitätsspalten für den Artikel definiert sind und keine automatische Identitätsverwaltung verwendet wird. Dies kann problematisch werden, wenn zwei Abonnenten denselben Identitätswert für eine neu eingefügte Zeile verwenden. Weitere Informationen zur Identitätsbereichsverwaltung finden Sie unter Replizieren von Identitätsspalten.

  • Konflikte, wenn der Merge-Agent aufgrund von Triggerlogik keine Zeilen in die Zieltabelle einfügen kann. Wenn beim Abonnenten beispielsweise ein UPDATE-Trigger vorhanden ist, der nicht als NFR gekennzeichnet ist und in seiner Logik ein ROLLBACK aufweist, gibt der Trigger im Fall eines Fehlers ein ROLLBACK für die Transaktion aus. Dies führt dazu, dass der Merge-Agent einen fehlerhaften Änderungskonflikt erkennt.