Freigeben über


Erkennen und Auflösen von Einschränkungskonflikten

Einschränkungskonflikte sind Konflikte, bei denen für Elemente geltende Einschränkungen (z. B. die Beziehung zwischen Ordnern oder der Speicherort identisch benannter Daten innerhalb eines Dateisystems) verletzt werden. Sync Framework stellt Änderungsanwenderobjekte bereit, mit denen Einschränkungskonflikte einfacher gelöst werden können.

Einschränkungskonflikte werden vom Zielanbieter während der Änderungsübernahmephase der Synchronisierung erkannt. Wenn der Zielanbieter einen Einschränkungskonflikt erkennt, meldet er diesen dem Änderungsanwender. Der Änderungsanwender löst den Konflikt entweder anhand der für die Sitzung festgelegten Richtlinie zur Konfliktauflösung oder der für die Anwendung für den angegebenen Konflikt festgelegten Konfliktauflösungsaktion auf. Der Änderungsanwender leitet dann alle notwendigen Aufrufe an den Zielanbieter weiter, damit dieser den aufgelösten Konflikt für das Zielreplikat übernehmen kann.

Wenn ein Anbieter Einschränkungskonflikte meldet und einen Änderungsanwender verwendet, muss zudem ein Konfliktprotokoll bereitgestellt werden, das der Änderungsanwender für die Verarbeitung und Protokollierung von Konflikten verwendet. Sync Framework stellt Anbietern eine speicherresidente Implementierung von Konfliktprotokollen bereit, die kein eigenes Konfliktprotokoll implementieren. Weitere Informationen finden Sie unter Protokollieren und Verwalten von Konflikten.

Beachten Sie, dass Einschränkungskonflikte nicht von Anbietern verwendet werden können, die benutzerdefinierte Filter oder den Änderungsübernahmedienst verwenden, da andernfalls unerwartete Ergebnisse auftreten können.

Arten von Einschränkungskonflikten

Einschränkungskonflikte sind abhängig vom dem vom Zielreplikat verwendeten Datenspeicher. Daher können sie viele verschiedene Formen annehmen. In Sync Framework werden Einschränkungskonflikte in die folgenden drei Arten unterteilt.

  • Ein Kollisionskonflikt tritt auf, wenn das Element nicht gespeichert werden kann, da es mit einem anderen Element im Zielspeicher in Konflikt steht, wenn beispielsweise der Quellenanbieter eine Datei sendet, die den gleichen Namen und Speicherort wie eine Datei aufweist, die bereits im Zielreplikat vorhanden ist.

  • Ein Konflikt aufgrund eines fehlenden übergeordneten Elements tritt auf, wenn ein Element nicht in einem hierarchischen Datenspeicher gespeichert werden kann, da es ein nicht vorhandenes übergeordnetes Element erfordert, wenn beispielsweise der Quellenanbieter eine Datei sendet, die in einem Verzeichnis gespeichert werden soll, das auf dem Zielreplikat nicht vorhanden ist.

  • Andere Einschränkungskonflikte treten auf, wenn das zu speichernde Element gegen eine Einschränkung des Zielreplikats verstößt, wenn beispielsweise der Quellenanbieter eine Datei sendet, die zu groß ist, um auf dem Zielreplikat gespeichert zu werden, oder wenn die Änderung gegen eine bestimmte Geschäftslogik des Zielreplikats verstößt. Ein Beispiel für einen Geschäftslogikkonflikt ist ein Replikat mit geringer Genauigkeit, in dem zwei Änderungseinheiten gespeichert wurden: name und country. Weiterhin kann ein Replikat mit hoher Genauigkeit mit den folgenden drei Änderungseinheiten auftreten: name, state/province und country. Das Replikat mit hoher Genauigkeit enthält die Geschäftslogik, die das Feld state/province anhand des Felds country prüft und die keine Änderungen speichert, die der Überprüfung nicht standhalten. Das Replikat mit niedriger Genauigkeit dient als Quelle und sendet ein Element, für das der Parameter country auf „USA“ festgelegt ist. Der Zielanbieter versucht, die Änderung für das Replikat mit hoher Genauigkeit zu übernehmen, das Element enthält jedoch auf dem Replikat mit hoher Genauigkeit im Feld state/province den Wert „British Columbia“. Daher verstößt die Änderung gegen die Geschäftslogik und verursacht einen Einschränkungskonflikt.

Der Zielanbieter wählt aus den folgenden Werten aus, um den Grund für einen Einschränkungskonflikt anzugeben.

Ursache für den Einschränkungskonflikt Beschreibung

Collision (für verwalteten Code), CCR_COLLISION (für nicht verwalteten Code)

Das Element kann nicht gespeichert werden, da ein Konflikt mit einem anderen Element im Speicher auftritt, z. B. mit einem Element, das den gleichen Namen wie ein vorhandenes Element aufweist. Der Anbieter muss die ID des Zielelements als die ID des Konflikt verursachenden Elements angeben.

NoParent (für verwalteten Code), CCR_NOPARENT (für nicht verwalteten Code)

Das Element kann nicht im hierarchischen Datenspeicher gespeichert werden, da es ein übergeordnetes Element erfordert, das im Speicher nicht vorhanden ist. Der Anbieter kann die ID des fehlenden übergeordneten Elements optional als ID des Konflikt verursachenden Elements angeben.

Other (für verwalteten Code), CCR_OTHER (für nicht verwalteten Code)

Das Element oder die Änderungseinheit verstößt gegen eine andere Einschränkung des Zielreplikats. Der Anbieter kann die ID des Konflikt verursachenden Elements optional als ID des Konflikt verursachenden Elements angeben.

Erkennen und Erstellen von Berichten über Einschränkungskonflikte

Ob ein Einschränkungskonflikt erkannt wird, ist abhängig vom dem von einem Replikat verwendeten Datenspeicher. Daher müssen Einschränkungskonflikte vom Zielanbieter erkannt werden. Beispielsweise muss ein Anbieter, der ein hierarchisches Dateisystem darstellt, speicherspezifische Einschränkungen erkennen können, die persistenten Daten auferlegt werden, z. B. Speicherort, Benennung, Größe usw.

Einschränkungskonflikte werden vom Zielanbieter während der Änderungsübernahmephase der Synchronisierung erkannt.

Verwalteter Code Einschränkungskonflikte werden in der Regel vom Zielanbieter in dessen SaveItemChange-Methode oder SaveChangeWithChangeUnits-Methode erkannt. Die Berichterstellung erfolgt, indem RecordConstraintConflictForItem oder RecordConstraintConflictForChangeUnit aufgerufen wird.

Nicht verwalteter Code Einschränkungskonflikte werden in der Regel vom Zielanbieter in dessen ISynchronousNotifyingChangeApplierTarget::SaveChange-Methode oder ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits-Methode erkannt. Die Berichterstellung erfolgt, indem ISaveChangeContext2::SetConstraintConflictOnChange oder ISaveChangeWithChangeUnitsContext2::SetConstraintConflictOnChangeUnit aufgerufen wird.

Wenn der Änderungsanwender einen Bericht zu einem Einschränkungskonflikt empfängt, führt er mehrere Aktionen durch:

  • Wenn es sich bei dem Einschränkungskonflikt um einen Kollisionskonflikt handelt, ermittelt der Änderungsanwender, ob es sich um einen neuen oder einen temporären Konflikt oder um eine Mergeauflösungsweitergabe handelt. Bei der Verarbeitung des Konflikts kann der Änderungsanwender den Konflikt temporär im Konfliktprotokoll speichern, indem er SaveConstraintConflict (für verwalteten Code) oder ISynchronousNotifyingChangeApplierTarget2::SaveConstraintConflict (für nicht verwalteten Code) aufruft. Der Änderungsanwender entfernt am Ende der Synchronisierungssitzung temporäre Konflikte aus dem Protokoll.

  • Löst Kollisionskonflikte entweder anhand der für die Sitzung festgelegten Richtlinie zur Kollisionskonfliktauflösung oder anhand der von der Anwendung festgelegten Konfliktauflösungsaktion auf. Die Anwendung wird aufgerufen, um die Konfliktauflösungsaktion zu bestimmen, wenn die Richtlinie zur Kollisionskonfliktauflösung auf ApplicationDefined (für verwalteten Code) oder CCRP_NONE (für nicht verwalteten Code) festgelegt wurde.

  • Löst Nicht-Kollisionseinschränkungskonflikte anhand der von der Anwendung festgelegten Konfliktauflösungsaktion auf. Für Nicht-Kollisionseinschränkungskonflikte kann keine Richtlinie zur Konfliktauflösung festgelegt werden.

Auflösen von Einschränkungskonflikten

Der Änderungsanwender hilft dem Zielanbieter, Einschränkungskonflikte aufzulösen, indem Aufrufe an das vom Anbieter angegebene Änderungsanwender-Zielobjekt weitergegeben werden. Wenn eine Richtlinie zur Kollisionskonfliktauflösung festgelegt wurde, wird diese vom Änderungsanwender verwendet, um die richtige Konfliktauflösungsaktion für das Auflösen der einzelnen auftretenden Kollisionskonflikte zu ermitteln. Wenn eine benutzerdefinierte Kollisionskonfliktauflösung festgelegt wird, benachrichtigt der Änderungsanwender die Synchronisierungsanwendung des Kollisionskonflikts, und die Anwendung gibt die Konfliktauflösungsaktion an. Für Nicht-Kollisionseinschränkungskonflikte kann keine Richtlinie zur Konfliktauflösung angegeben werden. Wenn ein Nicht-Kollisionseinschränkungskonflikt gemeldet wird, benachrichtigt der Änderungsanwender daher stets die Anwendung, damit diese die Konfliktauflösungsaktion angeben kann. In allen Fällen ruft der Änderungsanwender die entsprechende Zielmethode des Änderungsanwenders auf, und das Änderungsanwender-Zielobjekt führt die Aktion aus, z. B. das Speichern der Änderungen am Replikat oder das Protokollieren des Konflikts zur späteren Verarbeitung.

Festlegen einer Richtlinie für die Kollisionskonfliktauflösung

Von der Synchronisierungsanwendung wird in der Regel vor dem Starten der Synchronisierung eine Richtlinie für die Kollisionskonfliktauflösung festgelegt.

Verwalteter Code Die Anwendung legt die Richtlinie fest, indem die CollisionConflictResolutionPolicy-Eigenschaft des Zielanbieters auf den gewünschten Wert festgelegt wird.

Nicht verwalteter Code Die Anwendung legt die Richtlinie mithilfe eines benutzerdefinierten Mechanismus fest, z. B. einer benutzerdefinierten Schnittstelle, die die Anwendung erhält, indem für das Zielanbieterobjekt QueryInterface aufgerufen wird.

Der Zielanbieter übergibt die Richtlinie für die Kollisionskonfliktauflösung an die ApplyChanges-Methode (für verwalteten Code) oder die ISynchronousNotifyingChangeApplier2::ApplyChanges-Methode (für nicht verwalteten Code) des Änderungsanwenders, damit dieser die Methoden ordnungsgemäß an das Änderungsanwenderziel weiterleiten kann. Das Änderungsanwenderziel wird durch das INotifyingChangeApplierTarget2-Objekt (für verwalteten Code) oder das ISynchronousNotifyingChangeApplierTarget2-Objekt (für nicht verwalteten Code) dargestellt.

Richtlinien für die Kollisionskonfliktauflösung für verwalteten Code

In Sync Framework werden die folgenden Richtlinien für die Kollisionskonfliktauflösung für verwalteten Code definiert.

Richtlinie zur Konfliktlösung Beschreibung

SourceWins

Die am Quellreplikat vorgenommene Änderung hat stets Vorrang. Sync Framework legt die Konfliktauflösungsaktion SourceWins fest.

DestinationWins

Die am Zielreplikat vorgenommene Änderung hat stets Vorrang. Sync Framework legt die Konfliktauflösungsaktion DestinationWins fest.

RenameSource

Die vom Quellenanbieter gesendete Änderung wird umbenannt, um die Kollision mit dem konfliktverursachenden Element auf dem Zielreplikat aufzulösen, und die Quelländerung wird für das Zielreplikat übernommen. In Sync Framework wird die Konfliktauflösungsaktion RenameSource festgelegt.

RenameDestination

Das Konflikt verursachende Element auf dem Zielreplikat wird umbenannt, um die Kollision mit der vom Quellenanbieter gesendeten Änderung aufzulösen, und die Quelländerung wird für das Zielreplikat übernommen. In Sync Framework wird die Konfliktauflösungsaktion RenameDestination festgelegt.

Merge

Die Daten vom Quellelement werden mit dem Zielelement kombiniert. In Sync Framework wird die Konfliktauflösungsaktion Merge festgelegt.

ApplicationDefined

Der Änderungsanwender benachrichtigt die Synchronisierungsanwendungen mithilfe des Ereignisses ItemConstraint beim Auftreten von Kollisionskonflikten. Die Anwendung untersucht die Konflikt verursachenden Elemente und legt die Konfliktauflösungsaktion fest, indem SetResolutionAction aufgerufen wird.

Richtlinien für die Kollisionskonfliktauflösung für nicht verwalteten Code

In Sync Framework werden die folgenden Richtlinien für die Kollisionskonfliktauflösung für nicht verwalteten Code definiert.

Richtlinie zur Konfliktlösung Beschreibung

CCRP_SOURCE_PROVIDER_WINS

Die am Quellreplikat vorgenommene Änderung hat stets Vorrang. Sync Framework legt die Konfliktauflösungsaktion SCRA_ACCEPT_SOURCE_PROVIDER fest.

CCRP_DESTINATION_PROVIDER_WINS

Die am Zielreplikat vorgenommene Änderung hat stets Vorrang. Sync Framework legt die Konfliktauflösungsaktion SCRA_ACCEPT_DESTINATION_PROVIDER fest.

CCRP_RENAME_SOURCE

Die vom Quellenanbieter gesendete Änderung wird umbenannt, um die Kollision mit dem Konflikt verursachenden Element auf dem Zielreplikat aufzulösen, und die Quelländerung wird für das Zielreplikat übernommen. In Sync Framework wird die Konfliktauflösungsaktion SCRA_RENAME_SOURCE festgelegt.

CCRP_RENAME_DESTINATION

Das Konflikt verursachende Element auf dem Zielreplikat wird umbenannt, um die Kollision mit der vom Quellenanbieter gesendeten Änderung aufzulösen, und die Quelländerung wird für das Zielreplikat übernommen. In Sync Framework wird die Konfliktauflösungsaktion SCRA_RENAME_DESTINATION festgelegt.

CCRP_MERGE

Die Daten vom Quellelement werden mit dem Zielelement kombiniert. In Sync Framework wird die Konfliktauflösungsaktion SCRA_MERGE festgelegt.

CCRP_NONE

Der Änderungsanwender benachrichtigt die Synchronisierungsanwendungen mithilfe des Ereignisses ISyncConstraintCallback::OnConstraintConflict beim Auftreten von Kollisionskonflikten. Die Anwendung untersucht die Konflikt verursachenden Elemente und legt die Konfliktauflösungsaktion fest, indem IConstraintConflict::SetConstraintResolveActionForChange oder IConstraintConflict::GetConstraintResolveActionForChangeUnit aufgerufen wird.

Festlegen von benutzerdefinierten Konfliktauflösungen

Eine Anwendung kann angeben, dass für jeden auftretenden Einschränkungskonflikt eine Konfliktauflösungsaktion festgelegt wird. Um dies zu erreichen, registriert die Anwendung den Erhalt von Benachrichtigungen über Einschränkungskonflikte. Wenn ein Einschränkungskonflikt gemeldet wird, wird die Anwendung von Sync Framework benachrichtigt. Auf diese Weise kann der Konflikt von der Anwendung analysiert und anschließend die gewünschte Konfliktauflösungsaktion festlegt werden.

Festlegen von benutzerdefinierten Konfliktauflösungen unter Verwendung von verwaltetem Code

Um Benachrichtigungen über Kollisionskonflikte zu empfangen, werden vor dem Starten der Synchronisierung von einer Anwendung die folgenden Aktionen durchgeführt.

  • Es wird ein Ereignishandler für das ItemConstraint-Ereignis des Zielanbieters registriert.

  • Die CollisionConflictResolutionPolicy-Eigenschaft des Zielanbieters wird auf ApplicationDefined festgelegt.

Wenn diese Schritte von der Anwendung durchgeführt wurden, löst der Änderungsanwender für jeden bei der Synchronisierung auftretenden Kollisionseinschränkungskonflikt das ItemConstraint-Ereignis aus.

Da für Nicht-Kollisionseinschränkungskonflikte keine Richtlinie für die Konfliktauflösung festgelegt werden kann, löst der Änderungsanwender auch für jeden gemeldeten Nicht-Kollisionseinschränkungskonflikt das Ereignis ItemConstraint aus.

Der Ereignishandler für das ItemConstraint-Ereignis erhält ein ItemConstraintEventArgs-Objekt, das Meta- und Elementdaten für die beiden in Konflikt stehenden Änderungen enthält. Mit dem Ereignishandler können die zwei in Konflikt stehenden Änderungen untersucht, Änderungen an den Meta- oder Elementdaten vorgenommen und die Auflösungsaktion für den Konflikt mithilfe der SetResolutionAction-Methode festgelegt werden. Der Änderungsanwender verarbeitet anschließend den Konflikt und leitet den entsprechenden Aufruf an das Änderungsanwender-Zielobjekt weiter. Beachten Sie, dass für Einschränkungskonflikte, bei denen es sich nicht um eine Kollision handelt, lediglich die Konfliktauflösungsaktionen SaveConflict und SkipChange gelten.

Sync Framework stellt die folgenden Einschränkungskonflikt-Auflösungsaktionen bereit, für die der Änderungsanwender den Großteil der Verarbeitung übernimmt.

Konfliktauflösungsaktion Beschreibung Gültig für Konflikttyp

SourceWins

Die am Quellreplikat vorgenommene Änderung hat Vorrang. Der Änderungsanwender übergibt die Änderung an die SaveItemChange-Methode und legt die Speicheraktion DeleteConflictingAndSaveSourceItem fest. Die Quelländerung wird für das Zielreplikat übernommen, und das konfliktverursachende Zielreplikat wird vom Zielreplikat gelöscht.

Nur Kollisionskonflikte.

DestinationWins

Die am Zielreplikat vorgenommene Änderung hat Vorrang. Der Änderungsanwender übergibt die Quelländerung an die SaveItemChange-Methode und legt die Speicheraktion DeleteAndStoreTombstone fest. Der Zielanbieter erstellt einen Tombstone für die Quelländerung. Wenn das Ziel bei einer späteren Synchronisierung als Quelle dient, wird eine Änderung aufgelistet, die dem Löschen des Quellelements entspricht, um dieses aus der Synchronisierungscommunity zu entfernen.

Nur Kollisionskonflikte.

RenameSource

Die vom Quellenanbieter gesendete Änderung wird umbenannt, damit diese auf dem Zielreplikat nicht mehr auf das Konflikt verursachende Element trifft. Außerdem wird die Quelländerung für das Zielreplikat übernommen. Der Änderungsanwender übergibt die Änderung an die SaveItemChange-Methode und legt die Speicheraktion RenameSourceAndUpdateVersionAndData fest.

Nur Kollisionskonflikte.

RenameDestination

Das Konflikt verursachende Element auf dem Zielreplikat wird umbenannt, damit es nicht mehr auf die vom Quellenanbieter gesendete Änderung trifft. Außerdem wird die Quelländerung für das Zielreplikat übernommen. Der Änderungsanwender übergibt die Änderung an die SaveItemChange-Methode und legt die Speicheraktion RenameDestinationAndUpdateVersionData fest.

Nur Kollisionskonflikte.

Merge

Die Daten des Quellelements werden mit dem Zielelement kombiniert. Der Änderungsanwender übergibt die Änderungsdaten des Quellreplikats an die SaveItemChange-Methode und legt die Speicheraktion ChangeIdUpdateVersionAndMergeData fest. Weitere Informationen finden Sie im Folgenden unter Zusammenführen von Konflikt verursachenden Elementen.

Nur Kollisionskonflikte.

SaveConflict

Der Konflikt wird protokolliert, und die Änderung wird nicht übernommen. Der Änderungsanwender übergibt die Konfliktdaten an die SaveConstraintConflict-Methode, die den Konflikt in einem Konfliktprotokoll speichert. Weitere Informationen zur Protokollierung von Konflikten finden Sie unter Protokollieren und Verwalten von Konflikten.

Alle Einschränkungskonflikte.

SkipChange

Der Konflikt wird ignoriert, und die Änderung wird nicht übernommen. Der Änderungsanwender übergibt die Konfliktdaten nicht an den Zielanbieter.

Alle Einschränkungskonflikte.

Festlegen von benutzerdefinierten Konfliktauflösungen unter Verwendung von nicht verwaltetem Code

Um Benachrichtigungen über Kollisionskonflikte zu empfangen, werden vor dem Starten der Synchronisierung von einer Anwendung die folgenden Aktionen durchgeführt.

Wenn diese Schritte von der Anwendung durchgeführt wurden, ruft der Änderungsanwender für jeden bei der Synchronisierung auftretenden Kollisionseinschränkungskonflikt die OnConstraintConflict-Methode auf.

Da für Nicht-Kollisionseinschränkungskonflikte keine Richtlinie für die Konfliktauflösung festgelegt werden kann, ruft der Änderungsanwender auch für jeden gemeldeten Nicht-Kollisionseinschränkungskonflikt die OnConstraintConflict-Methode auf.

Die OnConstraintConflict-Methode empfängt ein IConstraintConflict-Objekt, das Meta- und Elementdaten für die beiden Konflikt verursachenden Änderungen enthält. Mit der Methode können die beiden Konflikt verursachenden Änderungen untersucht, Änderungen an den Meta- oder Elementdaten vorgenommen und die Auflösungsaktion für den Konflikt mithilfe der IConstraintConflict::SetConstraintResolveActionForChange-Methode oder der IConstraintConflict::GetConstraintResolveActionForChangeUnit-Methode festgelegt werden. Der Änderungsanwender verarbeitet anschließend den Konflikt und leitet den entsprechenden Aufruf an das Änderungsanwender-Zielobjekt weiter. Beachten Sie, dass für Einschränkungskonflikte, bei denen es sich nicht um eine Kollision handelt, lediglich die Konfliktauflösungsaktionen SCRA_TRANSFER_AND_DEFER und SCRA_DEFER gelten.

Sync Framework stellt die folgenden Einschränkungskonflikt-Auflösungsaktionen bereit, für die der Änderungsanwender den Großteil der Verarbeitung übernimmt.

Richtlinie zur Konfliktlösung Beschreibung Gültig für Inhaltstyp

SCRA_ACCEPT_SOURCE_PROVIDER

Die am Quellreplikat vorgenommene Änderung hat stets Vorrang. Der Änderungsanwender übergibt die Änderung an die ISynchronousNotifyingChangeApplierTarget::SaveChange-Methode und legt die Speicheraktion SSA_DELETE_CONFLICTING_AND_SAVE_SOURCE_ITEM fest. Die Quelländerung wird für das Zielreplikat übernommen, und das konfliktverursachende Zielreplikat wird vom Zielreplikat gelöscht.

Nur Kollisionskonflikte.

SCRA_ACCEPT_DESTINATION_PROVIDER

Die auf dem Zielreplikat vorgenommene Änderung hat stets Vorrang. Der Änderungsanwender übergibt die Quelländerung an die SaveChange-Methode und legt die Speicheraktion SSA_DELETE_AND_STORE_TOMBSTONE fest. Der Zielanbieter erstellt einen Tombstone für die Quelländerung. Wenn das Ziel bei einer späteren Synchronisierung als Quelle dient, wird eine Änderung aufgelistet, die dem Löschen des Quellelements entspricht, um dieses aus der Synchronisierungscommunity zu entfernen.

Nur Kollisionskonflikte.

SCRA_RENAME_SOURCE

Die vom Quellenanbieter gesendete Änderung wird umbenannt, damit diese auf dem Zielreplikat nicht mehr auf das Konflikt verursachende Element trifft. Außerdem wird die Quelländerung für das Zielreplikat übernommen. Der Änderungsanwender übergibt die Änderung an die SaveChange-Methode und legt die Speicheraktion SSA_RENAME_SOURCE_AND_UPDATE_VERSION_AND_DATA fest.

Nur Kollisionskonflikte.

SCRA_RENAME_DESTINATION

Das Konflikt verursachende Element auf dem Zielreplikat wird umbenannt, damit es nicht mehr auf die vom Quellenanbieter gesendete Änderung trifft. Außerdem wird die Quelländerung für das Zielreplikat übernommen. Der Änderungsanwender übergibt die Änderung an die SaveChange-Methode und legt die Speicheraktion SSA_RENAME_DESTINATION_AND_UPDATE_VERSION_AND_DATA fest.

Nur Kollisionskonflikte.

SCRA_MERGE

Die Daten des Quellelements werden mit dem Zielelement kombiniert. Der Änderungsanwender übergibt die Änderungsdaten des Quellreplikats an die SaveChange-Methode und legt die Speicheraktion SSA_CHANGE_ID_UPDATE_VERSION_AND_MERGE_DATA fest. Weitere Informationen finden Sie im Folgenden unter Zusammenführen von Konflikt verursachenden Elementen.

Nur Kollisionskonflikte.

SCRA_TRANSFER_AND_DEFER

Der Konflikt wird protokolliert, und die Änderung wird nicht übernommen. Der Änderungsanwender übergibt die Konfliktdaten an die ISynchronousNotifyingChangeApplierTarget2::SaveConstraintConflict-Methode, die den Konflikt in einem Konfliktprotokoll speichert. Weitere Informationen zur Protokollierung von Konflikten finden Sie unter Protokollieren und Verwalten von Konflikten.

Alle Einschränkungskonflikte.

SCRA_DEFER

Der Konflikt wird ignoriert, und die Änderung wird nicht übernommen. Der Änderungsanwender übergibt die Konfliktdaten nicht an den Zielanbieter.

Alle Einschränkungskonflikte.

Zusammenführen von Konflikt verursachenden Elementen

Das Zusammenführen zweier Elemente in einem Kollisionseinschränkungskonflikt unterscheidet sich vom Zusammenführen von Elementen in einem Parallelitätskonflikt, da die beiden in einem Kollisionskonflikt beteiligten Elemente unterschiedliche Element-IDs aufweisen. So wird beispielsweise auf einem Replikat die Datei „Lieblingsplatten.txt“ erstellt und mit der Element-ID id1 versehen. Auch auf einem anderen Replikat wird eine Datei „Lieblingsplatten.txt“ erstellt und mit der Element-ID id2 versehen. Wenn die Replikate synchronisiert werden, werden die beiden Elemente in Sync Framework als unterschiedliche Elemente behandelt, da sie verschiedene Element-IDs aufweisen. Vom Zielreplikat werden sie jedoch als identisches Element behandelt, da sie über den gleichen Namen verfügen. Daher meldet der Zielanbieter einen Kollisionskonflikt und legt fest, dass die Inhalte der beiden Elemente zusammengeführt werden sollen. Der Änderungsanwender weist dem zusammengeführten Element die ID id1 zu und legt fest, dass das Zielreplikat einen Mergetombstone für id2 speichern muss.

Wenn ein Kollisionskonflikt durch eine Zusammenführung aufgelöst wird, muss eine der Element-IDs ausgewählt werden, die Vorrang erhält und dem zusammengeführten Element zugewiesen wird. Außerdem muss ordnungsgemäß nachverfolgt werden, dass das nachrangige Element zusammengeführt wurde. Der Änderungsanwender wählt die vorrangige Element-ID aus, indem er die beiden Element-IDs vergleicht und die kleinere ID als vorrangige ID auswählt. Die vorrangige Element-ID wird verwendet, um das zusammengeführte Element auf dem Zielreplikat zu identifizieren. Ein Mergetombstone wird erstellt und wird im Zielreplikat gespeichert. Der Mergetombstone verfolgt nach, ob von der nachrangigen Element-ID in der Synchronisierungscommunity dasselbe Element wie von der vorrangigen Element-ID identifiziert wird. Die Metadaten für einen Mergetombstone sind abgesehen von der vorrangigen Element-ID mit denen eines Tombstones für ein gelöschtes Element identisch.

Verwalteter Code Wenn es sich bei der Änderungsauflösungsaktion um Merge handelt, ruft der Änderungsanwender SaveItemChange auf und legt die Speicheraktion ChangeIdUpdateVersionAndMergeData fest. Der Änderungsanwender übergibt die Änderung mit der nachrangigen Element-ID als change-Parameter weiter. Die Änderung mit der vorrangigen Element-ID kann abgerufen werden, indem die GetWinnerChange-Methode des SaveChangeContext-Objekts aufgerufen wird, die im context Parameter übergeben wurde.

Nicht verwalteter Code Wenn es sich bei der Änderungsauflösungsaktion um SCRA_MERGE handelt, ruft der Änderungsanwender ISynchronousNotifyingChangeApplierTarget::SaveChange auf und legt die Speicheraktion SSA_CHANGE_ID_UPDATE_VERSION_AND_MERGE_DATA fest. Der Änderungsanwender übergibt die Änderung mit der nachrangigen Element-ID als pChange-Parameter weiter. Die Änderung mit der vorrangigen Element-ID kann abgerufen werden, indem die ISaveChangeContext2::GetWinnerChange-Methode des ISaveChangeContext2-Objekts aufgerufen wird, die im pSaveContext Parameter übergeben wurde.

Der Zielanbieter muss mehrere Schritte ausführen, um die Zusammenführungsaktion ordnungsgemäß zu verarbeiten. Als Beispiel kann eine Zusammenführungsaktion dienen, bei der id1 der nachrangigen und id2 der vorrangigen Element-ID entspricht. Der Zielanbieter muss im Rahmen einer Transaktion die folgenden Schritte ausführen.

  1. Speichern Sie einen Mergetombstone in den Zielmetadaten. Der Mergetombstone enthält id1 als nachrangige und id2 als vorrangige Element-ID. Wenn auf dem Zielreplikat bereits ein Mergetombstone vorhanden ist, der id1 als nachrangige und id3 als vorrangige Element-ID enthält, führt der Anbieter die folgenden Schritte durch.

    1. Wenn id2 größer als id3 ist, erstellt und speichert der Anbieter zwei Mergetombstones. Ein Mergetombstone enthält id1 als nachrangige und id2 als vorrangige Element-ID. Der andere Mergetombstone enthält id2 als nachrangige und id3 als vorrangige Element-ID. Dieser zweite Mergetombstone ist möglicherweise bereits vorhanden. In diesem Fall wird keine Änderung an ihm vorgenommen. Auf diese Weise wird eine Kette von Mergetombstones in absteigender Reihenfolge der Element-IDs erstellt.

    2. Wenn id3 größer als id2 ist, gibt der Anbieter einen Fehler zurück.

  2. Führt die Daten für das Element im Zielreplikat mit den Daten für das Element vom Quellenanbieter zusammen. Das Zielelement kann entweder als id1 oder als id2 identifiziert werden.

  3. Übernimmt die Metadaten für die Änderung für die Zielmetadaten und die zusammengeführten Daten für die Änderung für den Zielelementspeicher, wobei die vorrangige Element-ID id2 als Element-ID für die zusammengeführte Änderung verwendet wird. Die Metadaten für die Änderung können abgerufen werden, indem die GetWinnerChange-Methode von context (für verwalteten Code) oder die GetWinnerChange-Methode von pContext (für nicht verwalteten Code) aufgerufen wird.

Weitergeben eines zusammengeführten Elements

Die Weitergabe von zusammengeführten Elementen eines Kollisionseinschränkungskonflikts unterscheidet sich von der Weitergabe zusammengeführter Elemente eines Parallelitätskonflikts, da Konflikte mit einer vorrangigen, einer nachrangigen oder beiden Element-IDs auftreten können. So enthält Replikat X beispielsweise ein Element mit der ID id1, das aus Elementen mit den IDs id1 und id2 zusammengeführt wurde. Das Replikat Y enthält ein Element mit der ID id2, an dem lokale Änderungen vorgenommen wurden. Wenn das als id1 identifizierte zusammengeführte Element von Replikat X an Replikat Y gesendet wird, entsteht ein Konflikt, da id1 jetzt auf das gleiche Element wie id2 verweist.

Der Änderungsanwender hilft dem Zielanbieter beim Übernehmen einer Änderung des zusammengeführten Elements, indem Parallelitätskonflikte erkannt werden, die sowohl mit der vorrangigen Element-ID als auch mit der nachrangigen Element-ID auftreten. Zudem wird ermittelt, welche Aktion der Zielanbieter durchführen muss, um die Änderung des zusammengeführten Elements auf dem Zielreplikat zu übernehmen. Wenn der Zielanbieter beim Übernehmen einer Änderung des zusammengeführten Elements einen Einschränkungskonflikt erkennt, muss dieser Einschränkungskonflikt wie jeder andere gemeldet werden.

Der Änderungsanwender erkennt zudem, wenn beim Quell- und Zielreplikat keine Übereinstimmung bezüglich der Identität eines Elements besteht. So löst Replikat X beispielsweise einen Kollisionskonflikt zwischen Elementen mit den IDs id1 und id2 auf, indem die Elemente zusammengeführt und dem zusammengeführten Element id1 zugewiesen werden. Replikat Y löst einen Kollisionskonflikt zwischen Elementen mit den IDs id1 und id2 auf, indem das als id1 erkannte Element umbenannt und beide Elemente beibehalten werden. Replikat X sendet das als id1 erkannte zusammengeführte Element und einen Mergetombstone, der angibt, dass id2 mit id1 zusammengeführt wurde. Der Konflikt für id1 wird erkannt und als Parallelitätskonflikt aufgelöst. Der Konflikt für id2 wird erkannt und der Synchronisierungsanwendung als Identitätskonflikt gemeldet, indem die Konfliktursache als Identity (für verwalteten Code) oder CCR_IDENTITY (für nicht verwalteten Code) angegeben wird. Die Anwendung bestimmt, ob der Konflikt durch das Beibehalten der Quell- oder der Zieländerung aufgelöst werden soll.

Beachten Sie, dass in einigen Fällen, wenn der Quellenanbieter Änderungseinheitsfilter verwendet und der Zielanbieter ungefiltert ist, auch dann ein Identitätskonflikt auftreten kann, wenn das durch den Mergetombstone identifizierte Element aus dem Zielreplikat entfernt werden soll. Dies liegt an der Art, in der das gefilterte Wissen vom Änderungsanwender behandelt wird. Um eine ordnungsgemäße Synchronisierung und Weitergabe des Mergetombstones sicherzustellen, muss der Zielanbieter den Mergetombstone beibehalten und das den Konflikt verursachende Element aus dem Zielreplikat entfernen.

Wenn eine zusammengeführte Elementänderung vom Quellenanbieter gesendet wird, bestimmt der Änderungsanwender die Aktion, die der Zielanbieter ausführen muss, um die Änderung für das Zielreplikat zu übernehmen. In der folgenden Tabelle werden die Speicheraktionen, die der Änderungsanwender angeben kann, sowie die Aktionen aufgeführt, die der Anbieter ausführen muss, um die Änderung zu übernehmen.

Speicheraktion Anbieteraktionen

ChangeIdUpdateVersionAndSaveData (für verwalteten Code), SSA_CHANGE_ID_UPDATE_VERSION_AND_SAVE_DATA (für nicht verwalteten Code)

Speichern Sie anhand der weiter oben unter Zusammenführen von Konflikt verursachenden Elementen aufgeführten Schritte einen Mergetombstone für die nachrangige Element-ID. Übernehmen Sie die vorrangige Elementänderung.

ChangeIdUpdateVersionOnly (für verwalteten Code), SSA_CHANGE_ID_UPDATE_VERSION_ONLY (für nicht verwalteten Code)

Speichern Sie anhand der weiter oben unter Zusammenführen von Konflikt verursachenden Elementen aufgeführten Schritte einen Mergetombstone für die nachrangige Element-ID. Übernehmen Sie nur Metadaten für die vorrangige Elementänderung.

ChangeIdUpdateVersionAndDeleteAndStoreTombstone (für verwalteten Code), SSA_CHANGE_ID_UPDATE_VERSION_AND_DELETE_AND_STORE_TOMBSTONE (für nicht verwalteten Code)

Speichern Sie anhand der weiter oben unter Zusammenführen von Konflikt verursachenden Elementen aufgeführten Schritte einen Mergetombstone für die nachrangige Element-ID. Löschen Sie das von der vorrangigen Element-ID identifizierte Element, und speichern Sie einen entsprechenden Tombstone.

StoreMergeTombstone (für verwalteten Code), SSA_STORE_MERGE_TOMBSTONE (für nicht verwalteten Code)

Speichern Sie anhand der weiter oben unter Zusammenführen von Konflikt verursachenden Elementen aufgeführten Schritte einen Mergetombstone für die nachrangige Element-ID.

Hinweis

Alle Schritte in einer Speicheraktion müssen als unteilbare Aktionen übernommen werden.

Siehe auch

Verweis

ISaveChangeContext2-Schnittstelle
ISaveChangeWithChangeUnitsContext2-Schnittstelle
ISynchronousNotifyingChangeApplier2-Schnittstelle
ISynchronousNotifyingChangeApplierTarget2-Schnittstelle
SaveChangeContext
SaveChangeWithChangeUnitsContext
NotifyingChangeApplier
INotifyingChangeApplierTarget2

Konzepte

Konfliktbehandlung
Erkennen und Auflösen von Parallelitätskonflikten