Freigeben über


Erkennen und Auflösen von Parallelitätskonflikten

Parallelitätskonflikte treten auf, wenn das gleiche Element oder die gleiche Änderungseinheit auf zwei verschiedenen Replikaten geändert wird, die später synchronisiert werden. Sync Framework stellt ein Änderungsanwenderobjekt bereit, das die Erkennung und Auflösung von Parallelitätskonflikten vereinfacht.

Erkennen und Auflösen von Parallelitätskonflikten durch den Änderungsanwender

Ein Parallelitätskonflikt wird erkannt, wenn die Version einer Änderung im Zielreplikat nicht im Wissen des Quellreplikats enthalten ist.

Sync Framework stellt ein Änderungsanwenderobjekt bereit, das der Zielanbieter zur Erkennung von Parallelitätskonflikten verwenden kann. Der Änderungsanwender erkennt Parallelitätskonflikte, indem er für jedes Element in dem vom Quellenanbieter gesendeten Änderungsbatch die folgenden Schritte ausführt:

  1. Ermitteln, ob die Version des Elements im Zielreplikat im Wissen des Quellreplikats enthalten ist

  2. Wenn die Version im Zielreplikat des Elements nicht im Wissen des Quellreplikats enthalten ist, liegt für die Änderung ein Konflikt vor.

Nachdem der Änderungsanwender einen Parallelitätskonflikt erkannt hat, löst er diesen entweder anhand der für die Sitzung festgelegten Richtlinie für die Kollisionskonfliktauflösung oder mit der von der Anwendung festgelegten Konfliktauflösungsaktion für den entsprechenden Konflikt auf.

Erkennen von Parallelitätskonflikten mit einem Änderungsanwender

Um einen Änderungsanwender zur Erkennung von Änderungen zu verwenden, erstellt der Zielanbieter zuerst das Änderungsanwenderobjekt.

Verwalteter Code Erstellen Sie ein NotifyingChangeApplier-Objekt.

Nicht verwalteter Code Erstellen Sie ein ISynchronousNotifyingChangeApplier-Objekt, indem Sie IID_ISynchronousNotifyingChangeApplier an die IProviderSyncServices::CreateChangeApplier-Methode übergeben.

Der Zielanbieter muss als nächstes Versionsinformationen für jedes Element aus dem vom Quellenanbieter gesendeten Änderungsbatch bereitstellen. Hierfür gibt es die folgenden beiden Möglichkeiten:

  • Der Zielanbieter erstellt eine Liste mit Versionen, die dem vom Quellenanbieter gesendeten Änderungsbatch entspricht. Der Änderungsanwender überprüft anhand dieser Liste, ob die Zielversion eines Elements im Wissen des Quellreplikats enthalten ist.

    Verwalteter Code Um diese Liste zu generieren, erstellen Sie ein Objekt des Typs System.Collections.Generic.IEnumerable<Microsoft.Synchronization.ItemChange>. Fügen Sie für jedes Element im Änderungsbatch des Quellenanbieters einen Eintrag in dieser Liste mit der Version dieses Elements im Zielreplikat hinzu. Übergeben Sie diese Liste an den Änderungsanwender als destinationVersions-Parameter der entsprechenden Methodenüberladung, z. B. ApplyChanges.

    Nicht verwalteter Code Um diese Liste zu generieren, erstellen Sie ein IDestinationChangeVersionsBuilder-Objekt, indem Sie IProviderSyncServices::CreateDestinationChangeVersionsBuilder aufrufen. Fügen Sie für jedes Element im Änderungsbatch des Quellenanbieters einen Eintrag in dieser Liste mit der Version dieses Elements im Zielreplikat hinzu, indem Sie IDestinationChangeVersionsBuilder::AddItemMetadata aufrufen. Rufen Sie einen Enumerator für die Liste ab, indem Sie IDestinationChangeVersionsBuilder::GetChangeEnumerator aufrufen, und übergeben Sie den Enumerator als pDestinationVersions-Parameter der ApplyChanges-Methode an den Änderungsanwender.

  • Als Alternative übergibt der Zielanbieter dem Änderungsanwender keine Liste der Zielversionen. Stattdessen implementiert der Zielanbieter TryGetDestinationVersion (für verwalteten Code) oder ISynchronousNotifyingChangeApplierTarget::GetDestinationVersion (für nicht verwalteten Code). Der Änderungsanwender ruft diese Methode für jedes Element im Änderungsbatch des Quellenanbieters einmal auf. Bei dieser Methode schlägt der Zielanbieter die Version des Zielreplikats des Elements nach und gibt sie an den Änderungsanwender zurück, damit der Änderungsanwender bestimmen kann, ob die Änderung einen Konflikt verursacht.

Schließlich ruft der Zielanbieter die ApplyChanges-Methode (für verwalteten Code) oder die ISynchronousNotifyingChangeApplier::ApplyChanges-Methode (für nicht verwalteten Code) des Änderungsanwenders auf.

Auflösen von Parallelitätskonflikten mit einem Änderungsanwender

Der Änderungsanwender hilft einem Zielanbieter, Konflikte aufzulösen, indem Aufrufe an ein vom Anbieter angegebenes Änderungsanwender-Zielobjekt weitergegeben werden. Wenn eine Richtlinie zur Konfliktauflösung festgelegt wurde, wird diese vom Änderungsanwender verwendet, um die richtige Konfliktauflösungsaktion für die jeweiligen Konflikte zu ermitteln. Wenn eine benutzerdefinierte Konfliktauflösung festgelegt wird, benachrichtigt der Änderungsanwender die Synchronisierungsanwendung des Konflikts, und die Anwendung gibt die Konfliktauflösungsaktion an. In beiden 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.

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

Verwalteter Code Die Anwendung gibt die Richtlinie durch Festlegen der Eigenschaft ConflictResolutionPolicy des Zielanbieters auf den gewünschten Wert an.

Nicht verwalteter Code Die Anwendung gibt die Richtlinie im resolutionPolicy-Parameter der ISyncSession::Start-Methode an. Der Zielanbieter empfängt diese Richtlinie als resolutionPolicy-Parameter der IKnowledgeSyncProvider::ProcessChangeBatch-Methode.

Der Zielanbieter übergibt die Richtlinie zur Konfliktauflösung an den Änderungsanwender, damit der Änderungsanwender die Methoden ordnungsgemäß an das Änderungsanwenderziel weiterleiten kann. Das Änderungsanwenderziel wird durch das INotifyingChangeApplierTarget-Objekt (für verwalteten Code) oder das ISynchronousNotifyingChangeApplierTarget-Objekt (für nicht verwalteten Code) dargestellt.

Sync Framework definiert die folgenden Richtlinien zur Parallelitätskonfliktauflösung.

Richtlinie zur Konfliktlösung Beschreibung

SourceWins (für verwalteten Code), CRP_SOURCE_PROVIDER_WINS (für nicht verwalteten Code)

Die am Quellreplikat vorgenommene Änderung hat stets Vorrang. Dadurch wird eine schreibgeschützte Synchronisierungslösung unterstützt, in der das Zielreplikat nicht vertrauenswürdig ist. Sync Framework gibt eine Konfliktauflösungsaktion von SourceWins (für verwalteten Code) oder SRA_ACCEPT_SOURCE_PROVIDER (für nicht verwalteten Code) an.

DestinationWins (für verwalteten Code), CRP_DESTINATION_PROVIDER_WINS (für nicht verwalteten Code)

Die auf dem Zielreplikat vorgenommene Änderung hat stets Vorrang. Hierdurch wird ermöglicht, dass das Zielreplikat keine Änderungen verarbeitet, die von Remoteclients vorgenommen werden. Sync Framework gibt eine Konfliktauflösungsaktion von DestinationWins (für verwalteten Code) oder SRA_ACCEPT_DESTINATION_PROVIDER (für nicht verwalteten Code) an.

ApplicationDefined (für verwalteten Code), CRP_NONE (für nicht verwalteten Code)

Der Änderungsanwender benachrichtigt die Synchronisierungsanwendung mit dem ItemConflicting-Ereignis (für verwalteten Code) oder der ISyncCallback::OnConflict-Methode (für nicht verwalteten Code) über jeden auftretenden Konflikt. Die Anwendung untersucht die Konflikt verursachenden Elemente und gibt die Konfliktauflösungsaktion durch Aufrufen von SetResolutionAction (für verwalteten Code), IChangeConflict::SetResolveActionForChange oder IChangeConflict::SetResolveActionForChangeUnit (für nicht verwalteten Code) an.

Festlegen von benutzerdefinierten Konfliktauflösungen

Um die Konfliktauflösungsaktion für jeden auftretenden Parallelitätskonflikt dynamisch anzugeben, führt eine Anwendung vor dem Starten der Synchronisierung die folgenden Aktionen aus.

Verwalteter Code

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

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

Nicht verwalteter Code

Während der Synchronisierung löst der Änderungsanwender einmal für jeden erkannten Parallelitätskonflikt das ItemConflicting-Ereignis (für verwalteten Code) oder die ISyncCallback::OnConflict-Methode (für nicht verwalteten Code) aus. Die Anwendung kann die zwei im Konflikt befindlichen Änderungen untersuchen, Änderungen an den Metadaten- oder Elementdaten vornehmen und die Auflösungsaktion für den Konflikt mit der SetResolutionAction-Methode (für verwalteten Code), der IChangeConflict::SetResolveActionForChange-Methode oder der IChangeConflict::SetResolveActionForChangeUnit-Methode (für nicht verwalteten Code) festlegen. Der Änderungsanwender verarbeitet anschließend den Konflikt und leitet den entsprechenden Aufruf an das Änderungsanwender-Zielobjekt weiter.

Hinweis

Für alle Änderungseinheiten in einem Element, die einen Konflikt verursachen, muss die gleiche Konfliktauflösungsaktion angegeben werden. Andernfalls können unerwartete Ergebnisse auftreten. Wenn dieser Typ von Konfliktauflösung erforderlich ist, müssen Sie angeben, dass der Konflikt durch Zusammenführen aufgelöst wird, und die Auflösung im Zielanbieter durchführen.

Von verwaltetem Code verwendete Auflösungsaktionen für Parallelitätskonflikte

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

Konfliktauflösungsaktion Beschreibung

SourceWins

Die am Quellreplikat vorgenommene Änderung hat Vorrang. Der Änderungsanwender übergibt die Änderung an die SaveItemChange- oder SaveChangeWithChangeUnits-Methode und legt die Speicheraktion UpdateVersionAndData fest. Die Änderung wird genau wie eine keinen Konflikt verursachende Änderung in das Zielreplikat übernommen.

DestinationWins

Die am Zielreplikat vorgenommene Änderung hat Vorrang. Der Änderungsanwender übergibt eine reine Versionsänderung an die SaveItemChange- oder SaveChangeWithChangeUnits-Methode und legt die Speicheraktion UpdateVersionOnly fest. In den Metadaten auf dem Zielreplikat werden nur Versionsinformationen für das Element aktualisiert. Es werden keine Elementdatenänderungen vorgenommen.

Merge

Führen Sie die Daten aus dem Quellelement mit dem Zielelement zusammen. Der Änderungsanwender übergibt die Änderungsdaten des Quellreplikats an die SaveItemChange- oder SaveChangeWithChangeUnits-Methode und legt die Speicheraktion UpdateVersionAndMergeData fest. Der Zielanbieter kombiniert die Daten des Quellelements und des Zielelements und übernimmt das Ergebnis in das Zielreplikat.

SaveConflict

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

SkipChange

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

Der letzte Schreibvorgang hat Vorrang

Die zuletzt vorgenommene Änderung hat Vorrang. Die Anwendung ruft den Zeitpunkt der Änderung auf dem Quellreplikat und auf dem Zielreplikat durch Aufrufen von GetItemChangeTime oder GetChangeUnitChangeTime der zwei Änderungen ab. Die Anwendung vergleicht die beiden Male miteinander und legt die Konfliktauflösungsaktion fest, mit der die letzte Änderung übernommen wird. Wenn z. B. die Zieländerung zuletzt vorgenommen wurde, gibt die Anwendung eine Konfliktauflösungsaktion von DestinationWins an.

Von nicht verwaltetem Code verwendete Auflösungsaktionen für Parallelitätskonflikte

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

Konfliktauflösungsaktion Beschreibung

SRA_ACCEPT_SOURCE_PROVIDER

Die am Quellreplikat vorgenommene Änderung hat Vorrang. Der Änderungsanwender übergibt die Änderung an die ISynchronousNotifyingChangeApplierTarget::SaveChange- oder ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits-Methode und legt die Speicheraktion SSA_UPDATE_VERSION_AND_DATA fest. Die Änderung wird genau wie eine keinen Konflikt verursachende Änderung in das Zielreplikat übernommen.

SRA_ACCEPT_DESTINATION_PROVIDER

Die am Zielreplikat vorgenommene Änderung hat Vorrang. Der Änderungsanwender übergibt eine reine Versionsänderung an die SaveChange- oder SaveChangeWithChangeUnits-Methode und legt die Speicheraktion SSA_UPDATE_VERSION_ONLY fest. In den Metadaten auf dem Zielreplikat werden nur Versionsinformationen für das Element aktualisiert. Es werden keine Elementdatenänderungen vorgenommen.

SRA_MERGE

Führen Sie die Daten aus dem Quellelement mit dem Zielelement zusammen. Der Änderungsanwender übergibt die Änderungsdaten des Quellreplikats an die SaveChange-Methode oder die SaveChangeWithChangeUnits-Methode und legt die Speicheraktion SSA_UPDATE_VERSION_AND_MERGE_DATA fest. Der Zielanbieter kombiniert die Daten des Quellelements und des Zielelements und übernimmt das Ergebnis in das Zielreplikat.

SRA_TRANSFER_AND_DEFER

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

SRA_DEFER

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

Der letzte Schreibvorgang hat Vorrang

Die zuletzt vorgenommene Änderung hat Vorrang. Die Anwendung ruft den Zeitpunkt der Änderung auf dem Quellreplikat und auf dem Zielreplikat durch Aufrufen von ISupportLastWriteTime::GetItemChangeTime oder ISupportLastWriteTime::GetChangeUnitChangeTime der zwei Änderungen ab. Die Anwendung vergleicht die beiden Male miteinander und legt die Konfliktauflösungsaktion fest, mit der die letzte Änderung übernommen wird. Wenn z. B. die Zieländerung zuletzt vorgenommen wurde, gibt die Anwendung eine Konfliktauflösungsaktion von SRA_ACCEPT_DESTINATION_PROVIDER an.

Siehe auch

Verweis

ISynchronousNotifyingChangeApplier-Schnittstelle
ISynchronousNotifyingChangeApplierTarget-Schnittstelle
CONFLICT_RESOLUTION_POLICY-Enumeration
SYNC_RESOLVE_ACTION-Enumeration
NotifyingChangeApplier
INotifyingChangeApplierTarget
ConflictResolutionAction
ConflictResolutionPolicy

Konzepte

Konfliktbehandlung
Erkennen und Auflösen von Einschränkungskonflikten