Rilevamento e risoluzione dei conflitti di concorrenza
Si verifica un conflitto di concorrenza quando lo stesso elemento o unità di modifica viene modificata in due repliche diverse la cui sincronizzazione avverrà in seguito. In Sync Framework è disponibile un oggetto di applicazione modifiche che semplifica il rilevamento e la risoluzione dei conflitti di concorrenza.
Rilevamento e risoluzione dei conflitti di concorrenza da parte dell'oggetto di applicazione modifiche
Viene rilevato un conflitto di concorrenza quando la versione della replica di destinazione di una modifica non è contenuta nella conoscenza della replica di origine.
In Sync Framework è disponibile un oggetto di applicazione modifiche che il provider di destinazione può utilizzare per rilevare i conflitti di concorrenza. L'oggetto di applicazione modifiche rileva i conflitti di concorrenza eseguendo i passaggi seguenti per ogni elemento del batch di modifiche inviato dal provider di origine:
Determina se la versione della replica di destinazione dell'elemento è contenuta nella conoscenza della replica di origine.
Se la versione della replica di destinazione dell'elemento non è contenuta nella conoscenza della replica di origine, la modifica è in conflitto.
Dopo avere rilevato un conflitto di concorrenza, l'oggetto di applicazione modifiche lo risolve in base ai criteri di risoluzione impostati per la sessione o in base all'azione di risoluzione impostata dall'applicazione per il conflitto specificato.
Rilevamento di conflitti di concorrenza tramite un oggetto di applicazione modifiche
Per utilizzare un oggetto di applicazione modifiche per rilevare le modifiche, il provider di destinazione deve innanzitutto creare l'oggetto di applicazione modifiche.
Codice gestito Creare un oggetto NotifyingChangeApplier.
Codice non gestito Creare un oggetto ISynchronousNotifyingChangeApplier passando IID_ISynchronousNotifyingChangeApplier al metodo IProviderSyncServices::CreateChangeApplier.
Il provider di destinazione deve quindi fornire informazioni sulla versione per ogni elemento del batch di modifiche inviato dal provider di origine. È possibile eseguire tale operazione in due modi:
Il provider di destinazione compila un elenco di versioni corrispondente al batch delle modifiche inviate dal provider di origine. L'oggetto di applicazione modifiche utilizza questo elenco per determinare se la versione di destinazione di ogni elemento è contenuta nella conoscenza della replica di origine.
Codice gestito Per creare questo elenco, creare un oggetto di tipo System.Collections.Generic.IEnumerable<Microsoft.Synchronization.ItemChange>. Per ogni elemento del batch di modifiche del provider di origine, aggiungere un elemento all'elenco che contiene la versione della replica di destinazione dell'elemento. Passare questo elenco all'oggetto di applicazione modifiche come il parametro destinationVersions dell'overload del metodo appropriato, ad esempio ApplyChanges.
Codice non gestito Per creare questo elenco, creare un oggetto IDestinationChangeVersionsBuilder chiamando IProviderSyncServices::CreateDestinationChangeVersionsBuilder. Per ogni elemento del batch di modifiche del provider di origine, aggiungere un elemento all'elenco che contiene la versione della replica di destinazione dell'elemento chiamando IDestinationChangeVersionsBuilder::AddItemMetadata. Ottenere un enumeratore per l'elenco chiamando IDestinationChangeVersionsBuilder::GetChangeEnumerator e passare l'enumeratore all'oggetto di applicazione modifiche come il parametro pDestinationVersions del metodo ApplyChanges.
In alternativa, il provider di destinazione non passa 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 ISynchronousNotifyingChangeApplierTarget::GetDestinationVersion (per il codice non gestito). L'oggetto di applicazione modifiche chiama questo metodo una volta per ogni elemento del batch di modifiche del provider di origine. In questo metodo il provider di destinazione cerca la versione della replica di destinazione dell'elemento e la restituisce all'oggetto di applicazione modifiche affinché quest'ultimo possa determinare se la modifica è in conflitto.
Infine, il provider di destinazione chiama il metodo ApplyChanges (per il codice gestito) o ISynchronousNotifyingChangeApplier::ApplyChanges (per il codice non gestito) dell'oggetto di applicazione modifiche.
Utilizzo di un oggetto di applicazione modifiche per risolvere i conflitti di concorrenza
L'oggetto di applicazione modifiche assiste un provider di destinazione nella risoluzione dei conflitti inviando chiamate all'oggetto di destinazione dell'oggetto di applicazione modifiche specificato dal provider. Quando vengono specificati criteri di risoluzione dei conflitti, l'oggetto di applicazione modifiche li utilizza per determinare l'azione di risoluzione corretta da eseguire per risolvere ogni conflitto che si verifica. Quando viene specificata una risoluzione dei conflitti personalizzata, l'oggetto di applicazione modifiche notifica il conflitto all'applicazione di sincronizzazione e quest'ultima specifica l'azione di risoluzione. In ogni caso, l'oggetto di applicazione modifiche chiama il metodo di destinazione appropriato e l'oggetto di destinazione dell'oggetto di applicazione modifiche esegue l'azione, ad esempio salva la modifica nella replica o registra il conflitto per un'elaborazione successiva.
L'applicazione di sincronizzazione specifica in genere i criteri di risoluzione dei conflitti di concorrenza prima dell'avvio della sincronizzazione.
Codice gestito L'applicazione specifica i criteri impostando la proprietà ConflictResolutionPolicy del provider di destinazione sul valore desiderato.
Codice non gestito L'applicazione specifica i criteri nel parametro resolutionPolicy del metodo ISyncSession::Start. Il provider di destinazione riceve questi criteri come il parametro resolutionPolicy del metodo IKnowledgeSyncProvider::ProcessChangeBatch.
Il provider di destinazione passa i criteri di risoluzione dei conflitti all'oggetto di applicazione modifiche affinché quest'ultimo possa inviare correttamente i metodi al proprio oggetto di destinazione. La destinazione dell'oggetto di applicazione modifiche è rappresentata dall'oggetto INotifyingChangeApplierTarget (per il codice gestito) o da ISynchronousNotifyingChangeApplierTarget (per il codice non gestito).
In Sync Framework vengono definiti i criteri di risoluzione dei conflitti di concorrenza seguenti.
Criteri di risoluzione dei conflitti | Descrizione |
---|---|
SourceWins (per il codice gestito), CRP_SOURCE_PROVIDER_WINS (per il codice non gestito) |
La modifica apportata alla replica di origine prevale. In questo modo si garantisce il supporto di una soluzione di sincronizzazione di sola lettura nella quale la replica di destinazione non deve essere attendibile. Sync Framework specifica un'azione di risoluzione dei conflitti SourceWins (per il codice gestito) o SRA_ACCEPT_SOURCE_PROVIDER (per il codice non gestito). |
DestinationWins (per il codice gestito), CRP_DESTINATION_PROVIDER_WINS (per il codice non gestito) |
La modifica apportata alla replica di destinazione prevale. In questo modo è possibile supportare il caso in cui la replica di destinazione non utilizza le modifiche apportate dai client remoti. In Sync Framework viene specificata un'azione di risoluzione dei conflitti DestinationWins (per il codice gestito) o SRA_ACCEPT_DESTINATION_PROVIDER (per il codice non gestito). |
ApplicationDefined (per il codice gestito), CRP_NONE (per il codice non gestito) |
L'oggetto di applicazione modifiche notifica all'applicazione di sincronizzazione ogni conflitto che si verifica tramite l'evento ItemConflicting (per il codice gestito) o il metodo ISyncCallback::OnConflict (per il codice non gestito). L'applicazione esamina gli elementi in conflitto e specifica l'azione di risoluzione dei conflitti chiamando SetResolutionAction (per il codice gestito), IChangeConflict::SetResolveActionForChange o IChangeConflict::SetResolveActionForChangeUnit (per il codice non gestito). |
Risoluzioni personalizzate dei conflitti
Per specificare in modo dinamico l'azione di risoluzione dei conflitti per ogni conflitto di concorrenza che si verifica, un'applicazione esegue le azioni seguenti prima dell'avvio della sincronizzazione.
Codice gestito
Registrazione di un gestore dell'evento per l'evento ItemConflicting del provider di destinazione.
Impostazione della proprietà ConflictResolutionPolicy del provider di destinazione su ApplicationDefined.
Codice non gestito
Implementazione del metodo ISyncCallback::OnConflict e registrazione dell'oggetto ISyncCallback tramite la chiamata a ISyncSession::RegisterCallback.
Passaggio di CRP_NONE per il parametro resolutionPolicy di ISyncSession::Start.
Durante la sincronizzazione, l'oggetto di applicazione modifiche genera l'evento ItemConflicting (per il codice gestito) o il metodo ISyncCallback::OnConflict (per il codice non gestito) una volta per ogni conflitto di concorrenza rilevato. L'applicazione può esaminare le due modifiche in conflitto, apportare modifiche ai metadati o ai dati dell'elemento e impostare l'azione di risoluzione del conflitto utilizzando il metodo SetResolutionAction (per il codice gestito), IChangeConflict::SetResolveActionForChange o IChangeConflict::SetResolveActionForChangeUnit (per il codice non gestito). L'oggetto di applicazione modifiche elabora quindi il conflitto e invia la chiamata appropriata all'oggetto di destinazione dell'oggetto di applicazione modifiche.
Nota
La stessa azione di risoluzione dei conflitti deve essere specificata per tutte le unità di modifica in conflitto in un elemento perché potrebbero verificarsi risultati imprevisti. Quando questo tipo di risoluzione dei conflitti è necessario, specificare che il conflitto viene risolto tramite unione e gestire la risoluzione nel provider di destinazione.
Azioni di risoluzione dei conflitti di concorrenza utilizzate dal codice gestito
In Sync Framework è disponibile il set di azioni di risoluzione dei conflitti di concorrenza seguente, per il quale l'oggetto di applicazione modifiche gestisce gran parte dell'elaborazione.
Azione di risoluzione dei conflitti | Descrizione |
---|---|
SourceWins |
La modifica apportata alla replica di origine prevale. L'oggetto di applicazione modifiche passa la modifica al metodo SaveItemChange o SaveChangeWithChangeUnits e specifica un'azione di salvataggio di UpdateVersionAndData. La modifica viene applicata alla replica di destinazione esattamente come qualsiasi modifica non in conflitto. |
DestinationWins |
La modifica apportata alla replica di destinazione prevale. L'oggetto di applicazione modifiche passa una modifica della sola versione al metodo SaveItemChange o SaveChangeWithChangeUnits e specifica un'azione di salvataggio di UpdateVersionOnly. Solo le informazioni sulla versione per l'elemento vengono aggiornate nei metadati della replica di destinazione. Non vengono apportate modifiche ai dati dell'elemento. |
Eseguire l'unione dei dati dall'elemento di origine nell'elemento di destinazione. L'oggetto di applicazione modifiche passa i dati di modifica della replica di origine al metodo SaveItemChange o SaveChangeWithChangeUnits e specifica un'azione di salvataggio di UpdateVersionAndMergeData. Il provider di destinazione combina i dati dell'elemento di origine e quelli dell'elemento di destinazione e applica il risultato alla replica di destinazione. |
|
Registrare il conflitto e non applicare la modifica. L'oggetto di applicazione modifiche passa i dati relativi al conflitto al metodo SaveConflict che salva il conflitto in un log. Per ulteriori informazioni sulla registrazione dei conflitti, vedere Registrazione e gestione di conflitti. |
|
Ignorare il conflitto e non applicare la modifica. L'oggetto di applicazione modifiche non passa i dati relativi al conflitto al provider di destinazione. |
|
Il valore salvato per ultimo sovrascrive i precedenti |
La modifica più recente prevale. L'applicazione recupera l'ora in cui è stata apportata la modifica nella replica di origine e l'ora in cui la stessa è stata apportata alla replica di destinazione chiamando GetItemChangeTime o GetChangeUnitChangeTime sulle due modifiche. L'applicazione confronta le due ore e specifica l'azione di risoluzione dei conflitti che applica la modifica più recente. Ad esempio, se la modifica di destinazione è stata apportata per ultima, l'applicazione specifica un'azione di risoluzione dei conflitti DestinationWins. |
Azioni di risoluzione dei conflitti di concorrenza utilizzate dal codice non gestito
In Sync Framework è disponibile il set di azioni di risoluzione dei conflitti di concorrenza seguente, per il quale l'oggetto di applicazione modifiche gestisce gran parte dell'elaborazione.
Azione di risoluzione dei conflitti | Descrizione |
---|---|
SRA_ACCEPT_SOURCE_PROVIDER |
La modifica apportata alla replica di origine prevale. L'oggetto di applicazione modifiche passa la modifica al metodo ISynchronousNotifyingChangeApplierTarget::SaveChange o ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits e specifica un'azione di salvataggio di SSA_UPDATE_VERSION_AND_DATA. La modifica viene applicata alla replica di destinazione esattamente come qualsiasi modifica non in conflitto. |
SRA_ACCEPT_DESTINATION_PROVIDER |
La modifica apportata alla replica di destinazione prevale. L'oggetto di applicazione modifiche passa una modifica della sola versione al metodo SaveChange o SaveChangeWithChangeUnits e specifica un'azione di salvataggio di SSA_UPDATE_VERSION_ONLY. Solo le informazioni sulla versione per l'elemento vengono aggiornate nei metadati della replica di destinazione. Non vengono apportate modifiche ai dati dell'elemento. |
SRA_MERGE |
Eseguire l'unione dei dati dall'elemento di origine nell'elemento di destinazione. L'oggetto di applicazione modifiche passa i dati di modifica della replica di origine al metodo SaveChange o SaveChangeWithChangeUnits e specifica un'azione di salvataggio di SSA_UPDATE_VERSION_AND_MERGE_DATA. Il provider di destinazione combina i dati dell'elemento di origine e quelli dell'elemento di destinazione e applica il risultato alla replica di destinazione. |
SRA_TRANSFER_AND_DEFER |
Registrare il conflitto e non applicare la modifica. L'oggetto di applicazione modifiche passa i dati relativi al conflitto al metodo ISynchronousNotifyingChangeApplierTarget::SaveConflict che salva il conflitto in un log. Per ulteriori informazioni sulla registrazione dei conflitti, vedere Registrazione e gestione di conflitti. |
SRA_DEFER |
Ignorare il conflitto e non applicare la modifica. L'oggetto di applicazione modifiche non passa i dati relativi al conflitto al provider di destinazione. |
Il valore salvato per ultimo sovrascrive i precedenti |
La modifica più recente prevale. L'applicazione recupera l'ora in cui è stata apportata la modifica nella replica di origine e l'ora in cui la stessa è stata apportata alla replica di destinazione chiamando ISupportLastWriteTime::GetItemChangeTime o ISupportLastWriteTime::GetChangeUnitChangeTime sulle due modifiche. L'applicazione confronta le due ore e specifica l'azione di risoluzione dei conflitti che applica la modifica più recente. Ad esempio, se la modifica di destinazione è stata apportata per ultima, l'applicazione specifica un'azione di risoluzione dei conflitti SRA_ACCEPT_DESTINATION_PROVIDER. |
Vedere anche
Riferimento
Interfaccia ISynchronousNotifyingChangeApplier
Interfaccia ISynchronousNotifyingChangeApplierTarget
Enumerazione CONFLICT_RESOLUTION_POLICY
Enumerazione SYNC_RESOLVE_ACTION
NotifyingChangeApplier
INotifyingChangeApplierTarget
ConflictResolutionAction
ConflictResolutionPolicy
Concetti
Gestione dei conflitti
Rilevamento e risoluzione dei conflitti di vincoli