Gestione dei conflitti
Durante la sincronizzazione, il provider di destinazione riceve un batch di modifiche dal provider di origine tramite il metodo ProcessChangeBatch (per il codice gestito) o il metodo ProcessChangeBatch (per il codice non gestito). Il provider di destinazione deve quindi rilevare e gestire qualsiasi conflitto che si verifica a causa di questo elenco.
Rilevamento dei conflitti
Esistono due categorie di conflitti che possono verificarsi nella sincronizzazione: conflitti di concorrenza e conflitti di vincolo.
Conflitti di concorrenza
I conflitti di concorrenza si verificano quando la versione della replica di destinazione di una modifica non è contenuta nella conoscenza della replica di origine. Questi conflitti si verificano perché operazioni come aggiornamento-eliminazione e aggiornamento-aggiornamento influiscono sullo stesso elemento sincronizzato.
In genere, il provider di destinazione utilizza un oggetto di applicazione modifiche fornito da Sync Framework per rilevare i conflitti di concorrenza. L'oggetto di applicazione modifiche è rappresentato dall'oggetto NotifyingChangeApplier (per il codice gestito) o dall'interfaccia ISynchronousNotifyingChangeApplier (per il codice non gestito). Per utilizzare un oggetto di applicazione modifiche per il rilevamento delle modifiche, il provider di destinazione deve fornire informazioni sulla versione per ciascun elemento del batch di modifiche inviato dal provider di origine. È possibile eseguire tale operazione in due modi:
Il provider di destinazione crea un elenco di modifiche che corrisponde al batch di modifiche inviate dal provider di origine. Per ciascun elemento del batch di modifiche del provider di origine, il provider di destinazione aggiunge un elemento all'elenco che contiene la versione di questo elemento nella replica di destinazione. Questo elenco viene passato all'oggetto di applicazione modifiche. L'oggetto di applicazione modifiche lo utilizza per verificare che la versione di destinazione di ogni elemento sia contenuta nella conoscenza della replica di origine.
Il provider di destinazione non fornisce un elenco di versioni di destinazione all'oggetto di applicazione modifiche. Al contrario, il provider di destinazione implementa il metodo TryGetDestinationVersion (per il codice gestito) o il metodo ISynchronousNotifyingChangeApplierTarget::GetDestinationVersion (per il codice non gestito). Questo metodo viene chiamato una volta per ogni elemento del batch di modifiche del provider di origine.
Per comprendere meglio le operazioni eseguite dall'oggetto di applicazione modifiche per il rilevamento di un conflitto, considerare lo scenario in cui un provider di destinazione riceve un batch di modifiche da un provider di origine. Per rilevare i conflitti, per ogni elemento nel batch di modifiche vengono eseguiti i passaggi seguenti:
Il provider di destinazione determina se la versione della replica di destinazione dell'elemento è contenuta nella conoscenza della replica di origine.
Se la versione della replica di destinazione non è contenuta nella conoscenza della replica di origine, l'oggetto viene definito in conflitto.
Conflitti di vincolo
I conflitti di vincolo violano i vincoli imposti sugli elementi, ad esempio la relazione delle cartelle o il percorso di dati denominati in modo identico all'interno di un file system.
Poiché il rilevamento di un conflitto di vincolo dipende dall'archivio dati utilizzato da una replica, questi tipi di conflitti devono essere rilevati dal provider. Ad esempio, un provider che rappresenta un file system gerarchico deve essere in grado di rilevare vincoli specifici dell'archivio imposti su dati persistenti, ad esempio percorso, denominazione, dimensioni e così via.
Risoluzione dei conflitti
I conflitti possono essere risolti definendo un criterio di risoluzione dei conflitti che si applica a tutti i conflitti durante la sessione oppure gestendo un evento che si verifica una volta per ogni conflitto.
Impostazione di un criterio di risoluzione dei conflitti
Per specificare un criterio che verrà applicato a tutti i conflitti durante una sessione, un'applicazione specifica un criterio di risoluzione dei conflitti nella proprietà ConflictResolutionPolicy (per il codice gestito) oppure nel metodo ISyncSession::Start (per il codice non gestito) del provider di destinazione.
Impostazione di un'azione di risoluzione dei conflitti
Per impostare dinamicamente l'azione di risoluzione dei conflitti per ogni conflitto che si verifica, un'applicazione gestisce l'evento di conflitto dell'elemento tramite ItemConflicting (per il codice gestito) o ISyncCallback::OnConflict (per il codice non gestito). Questo evento viene generato solo quando il criterio di risoluzione dei conflitti è impostato su ApplicationDefined (per il codice gestito) o su CRP_NONE (per il codice non gestito).
Codice gestito Quando viene generato l'evento ItemConflicting, il gestore eventi riceve un oggetto ItemConflictingEventArgs che contiene metadati e dati dell'elemento per le due modifiche in conflitto. Il gestore eventi può esaminare i due conflitti, apportare le modifiche ai metadati o ai dati dell'elemento e impostare l'azione di risoluzione per il conflitto tramite il metodo SetResolutionAction. Successivamente Sync Framework elabora il conflitto ed effettua le chiamate appropriate al provider di origine o di destinazione per applicare eventuali modifiche.
Codice non gestito Quando viene generato ISyncCallback::OnConflict, il gestore eventi riceve un oggetto IChangeConflict che contiene i metadati e i dati dell'elemento per le due modifiche in conflitto. Il gestore eventi può esaminare i due conflitti, apportare le modifiche ai metadati o ai dati dell'elemento e impostare l'azione di risoluzione per il conflitto tramite il metodo IChangeConflict::SetResolveActionForChange. Successivamente Sync Framework elabora il conflitto ed effettua le chiamate appropriate al provider di origine o di destinazione per applicare eventuali modifiche.
Risoluzioni dei conflitti
Sync Framework fornisce il seguente set di azioni di risoluzione dei conflitti per il quale gestisce la maggior parte dell'elaborazione. Gli altri tipi di risoluzione dei conflitti possono essere eseguiti utilizzando direttamente le modifiche in conflitto nel gestore eventi del conflitto di elementi.
Risoluzione dei conflitti | Descrizione | Disponibilità come criterio della sessione o come azione dell'elemento? |
---|---|---|
Prevale l'origine |
La replica di origine prevale sempre. In questo modo viene supportata una soluzione di sincronizzazione di sola lettura nella quale la replica di destinazione non sarà considerata attendibile. L'oggetto di applicazione modifiche passa la modifica al metodo SaveItemChange (per il codice gestito) o al metodo ISynchronousNotifyingChangeApplierTarget::SaveChange (per il codice non gestito). La modifica viene applicata alla replica di destinazione come qualsiasi modifica non in conflitto. |
Entrambe |
Prevale la destinazione |
La replica di destinazione prevale sempre. In questo modo è possibile supportare il caso nel quale la replica di destinazione non utilizza le modifiche effettuate dai client remoti. L'oggetto di applicazione modifiche passa la modifica in conflitto al metodo SaveItemChange (per il codice gestito) o al metodo ISynchronousNotifyingChangeApplierTarget::SaveChange (per il codice non gestito) come modifica della sola versione. Solo le informazioni sulla versione vengono applicate ai metadati nella replica di destinazione. |
Entrambe |
Unione |
Unire le informazioni da un elemento a un altro. L'oggetto di applicazione modifiche passa la modifica in conflitto al metodo SaveItemChange (per il codice gestito) o al metodo ISynchronousNotifyingChangeApplierTarget::SaveChange (per il codice non gestito) come modifica dell'unione. I dati dell'elemento di origine e dell'elemento di destinazione vengono uniti e il risultato viene applicato alla replica di destinazione. |
Solo azione dell'elemento |
Registrazione |
Registrare il conflitto da gestire in un secondo momento e non applicare la modifica. L'oggetto di applicazione modifiche passa la modifica in conflitto al metodo SaveConflict (per il codice gestito) o al metodo ISynchronousNotifyingChangeApplierTarget::SaveConflict (per il codice non gestito). |
Solo azione dell'elemento |
Posticipazione |
Ignorare il conflitto e non applicare la modifica. L'oggetto di applicazione modifiche non passa la modifica in conflitto al provider di destinazione. |
Solo azione dell'elemento |
Conflitti salvati
Quando un conflitto viene registrato, viene chiamato il metodo SaveConflict (per il codice gestito) o il metodo SaveConflict (per il codice non gestito) anziché il metodo SaveItemChange (per il codice gestito) o il metodo SaveChange (per il codice non gestito). In questo caso, il provider deve salvare la conoscenza del conflitto, la modifica in conflitto e i dati del conflitto. Un'applicazione può successivamente enumerare questi conflitti dal log dei conflitti e risolverli in un secondo momento. È importante considerare che questo tipo di risoluzione dei conflitti è sempre una modifica locale. Di conseguenza, l'applicazione che risolve i conflitti deve applicare la risoluzione come modifica locale, aggiornare il conteggio e aggiungere la conoscenza del conflitto alla conoscenza locale.
Inoltre, un'applicazione che risolve i conflitti salvati deve gestire conflitti obsoleti. In particolare, quando un provider registra un nuovo conflitto, deve controllare il nuovo conflitto in base alla conoscenza per assicurarsi che il conflitto registrato sostituisca tutti i conflitti precedentemente registrati per quell'elemento. È anche necessario eseguire la pulizia dei conflitti obsoleti del log. Un'applicazione può eseguire la pulizia dei conflitti obsoleti in modo asincrono anziché nel provider. In questo caso, è necessario che l'applicazione verifichi che i conflitti non siano obsoleti prima di tentare di risolverli.
Riduzione dei conflitti tramite le unità di modifica
Il numero di conflitti può essere ridotto tramite l'utilizzo di unità di modifica per rappresentare modifiche degli elementi secondari. Quando vengono utilizzate le unità di modifica, vengono registrate le versioni per le unità di modifica anziché per l'elemento nel suo complesso. Di conseguenza, le modifiche apportate alle diverse unità di modifica nello stesso elemento non determineranno un conflitto. Per ulteriori informazioni, vedere Sincronizzazione delle unità di modifica.
Vedere anche
Riferimento
Interfaccia ISyncKnowledge
Interfaccia ISyncProvider
Interfaccia IKnowledgeSyncProvider
IKnowledgeSyncProvider::ProcessChangeBatch
Interfaccia ISynchronousNotifyingChangeApplierTarget
Interfaccia IAsynchronousNotifyingChangeApplierTarget
ISyncCallback::OnConflict
Enumerazione CONFLICT_RESOLUTION_POLICY
Enumerazione SYNC_RESOLVE_ACTION
SyncKnowledge
KnowledgeSyncProvider
INotifyingChangeApplierTarget
ItemConflicting
ConflictResolutionPolicy
ConflictResolutionAction
Concetti
Provider di sincronizzazione
Applicazione delle modifiche
Informazioni sulla conoscenza di sincronizzazione