Compartilhar via


Detectando e solucionando conflitos de simultaneidade

Os conflitos de simultaneidade ocorrem quando o mesmo item ou a mesma unidade de alteração é modificada em duas réplicas diferentes que são sincronizadas posteriormente. O Sync Framework fornece um objeto de aplicador de alterações que simplifica a detecção e a resolução de conflitos de simultaneidade.

Como o aplicador de alterações detecta e resolve conflitos de simultaneidade

Um conflito de simultaneidade é detectado quando a versão de uma alteração da réplica de destino não está contida no conhecimento da réplica de origem.

O Sync Framework fornece um objeto aplicador de alterações que o provedor de destino pode usar para detectar os conflitos de simultaneidade. O aplicador de alterações detecta os conflitos de simultaneidade executando as seguintes etapas para cada item no lote de alterações enviado pelo provedor de origem:

  1. Determina se a versão do item da réplica de destino está contida no conhecimento da réplica de origem.

  2. Se a versão do item da réplica de destino não estiver contida no conhecimento da réplica de origem, a alteração estará em conflito.

Ao detectar um conflito de simultaneidade, o aplicador de alterações resolve o conflito de acordo com a política de resolução de conflitos definida para a sessão, ou de acordo com a ação de resolução de conflitos definida pelo aplicativo para o conflito especificado.

Detectando conflitos de simultaneidade usando um aplicador de alterações

Para usar um aplicador de alterações para detectar alterações, o provedor de destino primeiro cria o objeto aplicador de alterações.

Código gerenciado Criar um objeto NotifyingChangeApplier.

Código não gerenciado Criar um objeto ISynchronousNotifyingChangeApplier passando IID_ISynchronousNotifyingChangeApplier para o método IProviderSyncServices::CreateChangeApplier.

Em seguida, o provedor de destino deve fornecer informações de versão de cada item do lote de alterações enviado pelo provedor de origem. Isso pode ser feito das duas maneiras a seguir:

  • O provedor de destino cria uma lista de versões correspondente ao lote de alterações enviadas pelo provedor de origem. O aplicador de alterações usa essa lista para determinar se a versão de destino de um item está contida no conhecimento da réplica de origem.

    Código gerenciado Para criar essa lista, crie um objeto do tipo System.Collections.Generic.IEnumerable<Microsoft.Synchronization.ItemChange>. Para cada item do lote de alterações do provedor de origem, adicione a essa lista um item que contenha a versão do item da réplica de destino. Passe essa lista para o aplicador de alterações como o parâmetro destinationVersions da sobrecarga do método apropriado, como ApplyChanges.

    Código não gerenciado Para criar essa lista, crie um objeto IDestinationChangeVersionsBuilder chamando IProviderSyncServices::CreateDestinationChangeVersionsBuilder. Para cada item do lote de alterações do provedor de origem, adicione a essa lista um item que contenha a versão do item da réplica de destino chamando IDestinationChangeVersionsBuilder::AddItemMetadata. Obtenha um enumerador para a lista chamando IDestinationChangeVersionsBuilder::GetChangeEnumerator e passe o enumerador para o aplicador de alterações como o parâmetro pDestinationVersions do método ApplyChanges.

  • Como alternativa, o provedor de destino não passa uma lista de versões de destino para o aplicador de alterações. Em vez disso, o provedor de destino implementa o método TryGetDestinationVersion (para código gerenciado) ou ISynchronousNotifyingChangeApplierTarget::GetDestinationVersion (para código não gerenciado). O aplicador de alterações chama esse método uma vez para cada item no lote de alterações do provedor de origem. Nesse método, o provedor de destino procura a versão do item da réplica de destino e a retorna para o aplicador de alterações, para que este possa determinar se a alteração está em conflito.

Finalmente, o provedor de destino chama o método ApplyChanges (para código gerenciado) ou ISynchronousNotifyingChangeApplier::ApplyChanges (para código não gerenciado) do aplicador de alterações.

Usando um aplicador de alterações para resolver conflitos de simultaneidade

O aplicador de alterações ajuda um provedor de destino a resolver conflitos despachando chamadas para o objeto de destino de um aplicador de alterações especificado pelo provedor. Quando uma política de resolução de conflitos é especificada, o aplicador de alterações a utiliza para determinar a ação correta de resolução de conflitos a ser executada para resolver cada conflito que ocorrer. Quando a resolução de conflitos personalizada é especificada, o aplicador de alterações notifica o conflito ao aplicativo de sincronização, e este especifica a ação de resolução de conflitos. Em qualquer situação, o aplicador de alterações chama o método de destino apropriado do aplicador de alterações e o objeto de destino do aplicador de alterações executa a ação. Por exemplo, salvar a alteração da réplica ou registrar em log o conflito para processamento posterior.

O aplicativo de sincronização geralmente especifica uma política de resolução de conflitos de simultaneidade antes do início da sincronização.

Código gerenciado O aplicativo especifica a política definindo a propriedade ConflictResolutionPolicy do provedor de destino com o valor desejado.

Código não gerenciado O aplicativo especifica a política no parâmetro resolutionPolicy do método ISyncSession::Start. O provedor de destino recebe essa política como o parâmetro resolutionPolicy do método IKnowledgeSyncProvider::ProcessChangeBatch.

O provedor de destino passa a política de resolução de conflitos para o aplicador de alterações para que este possa despachar métodos corretamente para o destino do aplicador de alterações. O destino do aplicador de alterações é representado pelo objeto INotifyingChangeApplierTarget (para código gerenciado) ou ISynchronousNotifyingChangeApplierTarget (para código não gerenciado)

O Sync Framework define as políticas de resolução de conflitos de simultaneidade a seguir.

Política de resolução de conflitos Descrição

SourceWins (para código gerenciado), CRP_SOURCE_PROVIDER_WINS (para código não gerenciado)

A alteração feita na réplica de origem sempre vence. Isso dá suporte a uma solução de sincronização somente leitura na qual na réplica de destino não deve ser confiável. O Sync Framework especifica uma ação de resolução de conflitos SourceWins (para código gerenciado) ou SRA_ACCEPT_SOURCE_PROVIDER (para código não gerenciado).

DestinationWins (para código gerenciado), CRP_DESTINATION_PROVIDER_WINS (para código não gerenciado)

A alteração feita na réplica de destino sempre vence. Isso dá suporte ao caso no qual a réplica de destino não consome alterações feitas por clientes remotos. O Sync Framework especifica uma ação de resolução de conflitos DestinationWins (para código gerenciado) ou SRA_ACCEPT_DESTINATION_PROVIDER (para código não gerenciado).

ApplicationDefined (para código gerenciado), CRP_NONE (para código não gerenciado)

O aplicador de alterações notifica cada conflito ao aplicativo de sincronização, à medida que eles ocorrem, usando o evento ItemConflicting (para código gerenciado) ou o método ISyncCallback::OnConflict (para código não gerenciado). O aplicativo examina os itens conflitantes e especifica a ação de resolução de conflitos chamando SetResolutionAction (para código gerenciado), ou IChangeConflict::SetResolveActionForChange ou IChangeConflict::SetResolveActionForChangeUnit (para código não gerenciado).

Especificando resoluções de conflitos personalizadas

Para especificar a ação de resolução de conflitos dinamicamente para cada conflito de simultaneidade que ocorre, um aplicativo executa as ações a seguir antes de iniciar a sincronização.

Código gerenciado

  • Registra um manipulador de eventos para o evento ItemConflicting do provedor de destino.

  • Define a propriedade ConflictResolutionPolicy do provedor de destino como ApplicationDefined.

Código não gerenciado

Durante a sincronização, o aplicador de alterações gera o evento ItemConflicting (para código gerenciado) ou o método ISyncCallback::OnConflict (para código não gerenciado) uma vez para cada conflito de simultaneidade que ele detectar. O aplicativo pode examinar as duas alterações em conflito, fazer alterações nos metadados ou nos dados do item e definir a ação de resolução do conflito usando o método SetResolutionAction (para código gerenciado), ou o método IChangeConflict::SetResolveActionForChange ou IChangeConflict::SetResolveActionForChangeUnit (para código não gerenciado). O aplicador de alterações processa o conflito e distribui a chamada apropriada para o objeto de destino do aplicador de alterações.

Dica

A mesma ação de resolução de conflitos deve ser especificada para todas as unidades de alteração conflitantes em um item; caso contrário, poderão ocorrer resultados inesperados. Quando esse tipo de resolução de conflitos for exigido, especifique que o conflito seja resolvido por mesclagem e manipule a resolução no provedor de destino.

Ações de resolução de conflitos de simultaneidade usadas pelo código gerenciado

O Sync Framework fornece o conjunto de ações de resolução de conflitos de simultaneidade a seguir, para as quais o aplicador de alterações manipula a maior parte do processamento.

Ação de resolução de conflitos Descrição

SourceWins

A alteração feita na réplica de origem vence. O aplicador de alterações passa a alteração para o método SaveItemChange ou SaveChangeWithChangeUnits e especifica uma ação de salvamento UpdateVersionAndData. A alteração é aplicada à réplica de destino exatamente como qualquer alteração não conflitante.

DestinationWins

A alteração feita na réplica de destino vence. O aplicador de alterações passa uma alteração somente de versão para o método SaveItemChange ou SaveChangeWithChangeUnits e especifica uma ação de salvamento UpdateVersionOnly. Somente as informações de versão do item são atualizadas nos metadados na réplica de destino. Nenhuma alteração de dados de item é feita.

Merge

Mescle os dados do item de origem no item de destino. O aplicador de alterações passa os dados de alteração da réplica de origem para o método SaveItemChange ou SaveChangeWithChangeUnits e especifica uma ação de salvamento UpdateVersionAndMergeData. O provedor de destino combina os dados do item de origem e os dados do item de destino e aplica o resultado à réplica de destino.

SaveConflict

Registre o conflito em log e não aplique a alteração. O aplicador de alterações passa os dados do conflito para o método SaveConflict, o qual salva o conflito em um log de conflitos. Para obter mais informações sobre como registrar os conflitos em log, consulte Registrando em log e gerenciando conflitos.

SkipChange

Ignore o conflito e não aplique a alteração. O aplicador de alterações não passa os dados do conflito para o provedor de destino.

O último gravador vence

A alteração feita mais recentemente vence. O aplicativo recupera a hora em que a alteração foi feita na réplica de origem e a hora em que a alteração foi feita na réplica de destino chamando GetItemChangeTime ou GetChangeUnitChangeTime nas duas alterações. O aplicativo compara os dois horários e especifica a ação de resolução de conflitos que aplica a alteração que foi feita por último. Por exemplo, quando a alteração de destino foi feita por último, o aplicativo especifica uma ação de resolução de conflitos DestinationWins.

Ações de resolução de conflitos de simultaneidade usadas pelo código não gerenciado

O Sync Framework fornece o conjunto de ações de resolução de conflitos de simultaneidade a seguir, para as quais o aplicador de alterações manipula a maior parte do processamento.

Ação de resolução de conflitos Descrição

SRA_ACCEPT_SOURCE_PROVIDER

A alteração feita na réplica de origem vence. O aplicador de alterações passa a alteração para o método ISynchronousNotifyingChangeApplierTarget::SaveChange ou ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits e especifica uma ação de salvamento SSA_UPDATE_VERSION_AND_DATA. A alteração é aplicada à réplica de destino exatamente como qualquer alteração não conflitante.

SRA_ACCEPT_DESTINATION_PROVIDER

A alteração feita na réplica de destino vence. O aplicador de alterações passa uma alteração somente de versão para o método SaveChange ou SaveChangeWithChangeUnits e especifica uma ação de salvamento SSA_UPDATE_VERSION_ONLY. Somente as informações de versão do item são atualizadas nos metadados na réplica de destino. Nenhuma alteração de dados de item é feita.

SRA_MERGE

Mescle os dados do item de origem no item de destino. O aplicador de alterações passa os dados de alteração da réplica de origem para o método SaveChange ou SaveChangeWithChangeUnits e especifica uma ação de salvamento SSA_UPDATE_VERSION_AND_MERGE_DATA. O provedor de destino combina os dados do item de origem e os dados do item de destino e aplica o resultado à réplica de destino.

SRA_TRANSFER_AND_DEFER

Registre o conflito em log e não aplique a alteração. O aplicador de alterações passa os dados do conflito para o método ISynchronousNotifyingChangeApplierTarget::SaveConflict, o qual salva o conflito em um log de conflitos. Para obter mais informações sobre como registrar os conflitos em log, consulte Registrando em log e gerenciando conflitos.

SRA_DEFER

Ignore o conflito e não aplique a alteração. O aplicador de alterações não passa os dados do conflito para o provedor de destino.

O último gravador vence

A alteração feita mais recentemente vence. O aplicativo recupera a hora em que a alteração foi feita na réplica de origem e a hora em que a alteração foi feita na réplica de destino chamando ISupportLastWriteTime::GetItemChangeTime ou ISupportLastWriteTime::GetChangeUnitChangeTime nas duas alterações. O aplicativo compara os dois horários e especifica a ação de resolução de conflitos que aplica a alteração que foi feita por último. Por exemplo, quando a alteração de destino foi feita por último, o aplicativo especifica uma ação de resolução de conflitos SRA_ACCEPT_DESTINATION_PROVIDER.

Consulte também

Referência

Interface ISynchronousNotifyingChangeApplier
Interface ISynchronousNotifyingChangeApplierTarget
Enumeração CONFLICT_RESOLUTION_POLICY
Enumeração SYNC_RESOLVE_ACTION
NotifyingChangeApplier
INotifyingChangeApplierTarget
ConflictResolutionAction
ConflictResolutionPolicy

Conceitos

Manipulando conflitos
Detectando e solucionando conflitos de restrição