Applicazione delle modifiche
Dopo il recupero di un batch di modifiche e la gestione dei conflitti da parte del provider di destinazione, è necessario applicare le modifiche alla replica di destinazione. In genere questa operazione viene eseguita nel metodo ProcessChangeBatch (per il codice gestito) o nel metodo ProcessChangeBatch (per il codice non gestito) del provider di destinazione e può essere completata facilmente tramite un oggetto di applicazione modifiche fornito da Sync Framework.
Modalità di applicazione delle modifiche
Dopo aver ottenuto il batch di modifiche dal provider di origine, il provider di destinazione applica le modifiche alla replica di destinazione. Un oggetto di applicazione modifiche fornito da Sync Framework può essere ottenuto creando un oggetto NotifyingChangeApplier (per il codice gestito) o chiamando IProviderSyncServices::CreateChangeApplier (per il codice non gestito). Il metodo ApplyChanges (per il codice gestito) o il metodo ApplyChanges (per il codice non gestito) rilevano conflitti e chiamano metodi nel provider di destinazione per applicare le modifiche alla replica di destinazione.
Elaborazione di un elemento di modifica
Per elaborare un elemento di modifica tipico, l'oggetto di applicazione modifiche chiama prima il metodo LoadChangeData (per il codice gestito) o il metodo ISynchronousDataRetriever::LoadChangeData (per il codice non gestito) nel provider di origine per avviare il trasferimento dei dati. Questo metodo restituisce object (per il codice gestito) o un'interfaccia IUnknown (per il codice non gestito) che rappresenta il meccanismo di trasferimento dei dati. L'oggetto di applicazione modifiche chiama quindi il metodo SaveItemChange (per il codice gestito) o il metodo ISynchronousNotifyingChangeApplierTarget::SaveChange (per il codice non gestito) nel provider di destinazione e passa l'oggetto di trasferimento dei dati come parte del contesto di salvataggio delle modifiche. Il provider di destinazione può quindi trasferire i dati alla replica di destinazione. Qualsiasi errore nel processo di ottenimento dei dati o nell'elaborazione delle modifiche viene indicato tramite il metodo RecordRecoverableErrorForItem (per il codice gestito) o il metodo ISaveChangeContext::SetRecoverableErrorOnChange (per il codice non gestito). Questo metodo registra un errore reversibile per questo elemento nell'oggetto conoscenza acquisita contenuto nel batch di modifiche.
Aggiornamento della conoscenza acquisita
Mentre vengono applicate le modifiche, l'oggetto di applicazione modifiche aggiorna la conoscenza acquisita contenuta nel batch di modifiche. La conoscenza acquisita è la conoscenza della replica di origine proiettata nelle modifiche del batch di modifiche e rappresenta ciò che verrà acquisito dalla replica di destinazione al momento dell'applicazione di tutte le modifiche nel batch di modifiche. La conoscenza acquisita viene aggiornata nei modi seguenti:
Se è stato applicato un solo sottoinsieme di modifiche a causa di interruzioni o annullamenti, l'oggetto di applicazione modifiche utilizza l'operatore Project per limitare la conoscenza solo all'insieme di modifiche applicato.
Se alcune modifiche non sono state applicate, l'oggetto di applicazione modifiche le esclude anche dalla conoscenza.
È importante considerare che i responsabili dell'implementazione del provider non devono eseguire manualmente queste operazioni di proiezione, unione ed esclusione, poiché l'oggetto di applicazione modifiche le esegue per conto del provider.
Salvataggio della conoscenza di destinazione aggiornata
Dopo essere stata aggiornata, la conoscenza acquisita viene combinata con la conoscenza della replica di destinazione. Il provider di destinazione deve sostituire la conoscenza della replica di destinazione con questa conoscenza in modalità atomica. Questa atomicità può essere ottenuta salvando la conoscenza aggiornata una sola volta per batch se tutte le modifiche in un batch vengono applicate all'interno di una sola transazione. L'oggetto di applicazione modifiche supporta questa operazione chiamando il metodo StoreKnowledgeForScope (per il codice gestito) o il metodo ISynchronousNotifyingChangeApplierTarget::SaveKnowledge (per il codice non gestito) nel provider di destinazione alla fine di ogni batch. La conoscenza passata a questo metodo è la conoscenza aggiornata da applicare alla replica di destinazione. In alternativa, il provider di destinazione può chiamare il metodo GetUpdatedDestinationKnowledge (per il codice gestito) o il metodo ISaveChangeContext::GetKnowledgeForScope (per il codice non gestito) per ottenere la conoscenza aggiornata.
Quando i provider utilizzano unità di modifica per rappresentare elementi secondari, si riscontrano alcune differenze nella modalità di applicazione delle modifiche. Per ulteriori informazioni, vedere Sincronizzazione delle unità di modifica.
Considerazioni speciali per repliche gerarchiche
La sincronizzazione di repliche gerarchiche può implicare alcune complicazioni causate dall'invio in batch di insiemi di modifiche dall'origine alla destinazione. Sync Framework non supporta il concetto di gerarchia dei dati. Di conseguenza, è compito dei provider gestire correttamente queste situazioni.
La complicazione più comune è l'ordine delle relazioni padre-figlio nelle operazioni di aggiornamento. Si consideri ad esempio lo scenario seguente:
La replica di origine ha creato una nuova cartella e un set di nuovi elementi al suo interno.
Il provider di destinazione richiede le modifiche dal provider di origine. Il provider di origine invia l'elenco di modifiche in due batch. Tuttavia, il batch di modifiche che contiene la creazione della cartella padre arriva dopo il batch di modifiche che contiene gli elementi figlio.
Il provider di destinazione deve decidere dove archiviare il set di elementi arrivati nel primo batch, poiché le informazioni su dove archiviarli arriveranno solo con il secondo batch.
Riduzione degli aggiornamenti gerarchici
In caso di aggiornamenti, il modo più semplice per ridurre le complessità relative alle relazioni padre-figlio consiste nell'affidare al provider di origine la responsabilità dell'ordinamento degli ID globali. In questo modo gli elementi padre arriveranno sempre prima degli elementi figlio.
Quando i provider di destinazione gestiscono la trasmissione di aggiornamenti eseguiti in un archivio gerarchico, è possibile che ricevano relazioni padre-figlio non ordinate. I provider di destinazione devono essere in grado di risolvere questa situazione eliminando la modifica non ordinata e annotando un'eccezione nella conoscenza oppure inserendo in coda la modifica da applicare in un secondo momento. Poiché gli elementi potrebbero essere di dimensioni elevate, eliminare semplicemente la modifica e annotare le eccezioni della conoscenza costituisce probabilmente l'approccio più efficace.
Riduzione delle eliminazioni gerarchiche
I provider di destinazione determinano se un elemento è un elemento contenitore. Per i contenitori vuoti, le eliminazioni possono verificarsi immediatamente. Tuttavia, se il contenitore dispone di elementi che non sono stati contrassegnati per l'eliminazione, il provider può effettuare una delle seguenti operazioni:
Inserire in coda le eliminazioni per un'elaborazione successiva. Dopo che tutti gli elementi figlio del contenitore sono stati contrassegnati per l'eliminazione, è possibile attivare l'eliminazione effettiva.
Eliminare questa richiesta e impostare un'eccezione nella conoscenza per indicare la ricezione non ordinata di un elemento.
Per affrontare scenari in cui nella gerarchia viene prima eliminato un elemento padre e successivamente viene aggiunto un elemento figlio, viene osservata la regola seguente: le eliminazioni in coda sono valide solo fino al termine di una sessione pairwise e non sono persistenti fra i partecipanti.
Vedere anche
Riferimento
Interfaccia IProviderSyncServices
ISynchronousNotifyingChangeApplier::ApplyChanges
IAsynchronousNotifyingChangeApplier::ApplyChanges
ISynchronousNotifyingChangeApplierTarget::SaveKnowledge
IAsynchronousNotifyingChangeApplierTarget::SaveKnowledge
Interfaccia ISynchronousDataRetriever
Interfaccia IAsynchronousDataRetriever
ISyncKnowledge::ExcludeItem
ISyncKnowledge::Union
Interfaccia ISaveChangeContext
NotifyingChangeApplier
ApplyChanges
StoreKnowledgeForScope
IChangeDataRetriever
ExcludeItem
Contains
SaveChangeContext
Concetti
Provider di sincronizzazione
Informazioni sulla conoscenza di sincronizzazione