Partilhar via


Detectando e solucionando conflitos de restrição

Conflitos de restrição são aqueles que violam as restrições dos itens, como a relação de pastas ou o local de dados que têm nomes idênticos em um sistema de arquivos. O Sync Framework fornece objetos aplicadores de alterações que simplificam a solução de conflitos de restrição.

Os conflitos de restrição são detectados pelo provedor de destino durante a fase de aplicação de alterações da sincronização. Quando o provedor de destino detecta um conflito de restrição, ele relata esse conflito ao aplicador de alterações. Este 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 definida pelo aplicativo para o conflito especificado. O aplicador de alterações então despacha as chamadas necessárias para o provedor de destino, para que este possa aplicar o conflito resolvido à réplica de destino.

Ao relatar conflitos de restrição e usar um aplicador de alterações, um provedor também deve fornecer um log de conflitos que o aplicador de alterações utilize para processar e registrar os conflitos em log. O Sync Framework fornece uma implementação de um log de conflitos na memória para os provedores que não implementam seus próprios logs de conflitos. Para obter mais informações, consulte Registrando em log e gerenciando conflitos.

Lembre-se de que conflitos de restrição não podem ser usados por um provedor que use filtros personalizados nem o serviço de aplicação de alteração, ou podem ocorrer resultados inesperados.

Tipos de conflitos de restrição

Os conflitos de restrição dependem do repositório de dados usado pela réplica de destino e, portanto, podem assumir muitas formas. O Sync Framework divide os conflitos de restrição nos três tipos a seguir.

  • Um conflito de colisão ocorre quando o item não pode ser salvo porque está em conflito com outro item no repositório de destino. Por exemplo, quando o provedor de origem envia um arquivo com os mesmos nome e local de um arquivo existente na réplica de destino.

  • Um conflito de pai ausente ocorre quando um item não pode ser salvo em um repositório de dados hierárquico porque ele requer um item pai que não existe. Por exemplo, quando o provedor de origem envia um arquivo a ser salvo em um diretório que não existe na réplica de destino.

  • Outros conflitos de restrição ocorrem quando o item a ser salvo viola uma restrição da réplica de destino. Por exemplo, quando o provedor de origem envia um arquivo muito grande para ser salvo na réplica de destino ou quando a alteração viola alguma lógica de negócios na réplica de destino. Como exemplo de um conflito de lógica corporativa, considere uma réplica de baixa-fidelidade que armazene duas unidades de alteração: name e country. Considere também uma réplica de baixa fidelidade que armazene três unidades de alteração: name, state/province e country. A réplica de alta fidelidade contém lógica corporativa que verifica o campo state/province em relação ao campo country e não armazenará uma alteração que não seja aprovada na verificação. A réplica da baixa fidelidade age como a origem e envia um item com country definido como "EUA". O provedor de destino tenta aplicar a alteração à réplica de alta fidelidade, porém, nessa réplica, o item contém "Columbia Britânica" em seu campo state/province. Portanto, a alteração viola a lógica de negócios e provoca um conflito de restrição.

O provedor de destino seleciona entre os valores a seguir para especificar o motivo de um conflito de restrição.

Motivo do conflito de restrição

Descrição

Collision (para código gerenciado), CCR_COLLISION (para código não gerenciado)

O item não pode ser salvo porque está em conflito com outro item no repositório. Por exemplo, um item com o mesmo nome de um item existente. O provedor deve especificar a ID do item de destino como a ID do item em conflito.

NoParent (para código gerenciado), CCR_NOPARENT (para código não gerenciado)

O item não pode ser salvo no repositório de dados hierárquico porque requer um item pai que não existe no repositório. O provedor pode, opcionalmente, especificar a ID do pai ausente como a ID do item em conflito.

Other (para código gerenciado), CCR_OTHER (para código não gerenciado)

O item ou a unidade de alteração viola alguma outra restrição da réplica de destino. O provedor pode, opcionalmente, especificar a ID do item em conflito como a ID do item em conflito.

Detectando e relatando conflitos de restrição

A detecção de um conflito de restrição depende do repositório de dados usado por uma réplica. Portanto, os conflitos de restrição devem ser detectados pelo provedor de destino. Por exemplo, um provedor que representa um sistema de arquivos hierárquico deve poder detectar restrições específicas do repositório que são postas em dados persistentes, como local, nomenclatura, tamanho etc.

Os conflitos de restrição são detectados pelo provedor de destino durante a fase de aplicação de alterações da sincronização.

Código gerenciado Os conflitos de restrição geralmente são detectados pelo provedor de destino em seu método SaveItemChange ou SaveChangeWithChangeUnits e são relatados por meio da chamada de RecordConstraintConflictForItem ou RecordConstraintConflictForChangeUnit.

Código não gerenciado Os conflitos de restrição geralmente são detectados pelo provedor de destino em seu método ISynchronousNotifyingChangeApplierTarget::SaveChange ou ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits e são relatados por meio da chamada de ISaveChangeContext2::SetConstraintConflictOnChange ou ISaveChangeWithChangeUnitsContext2::SetConstraintConflictOnChangeUnit.

Quando o aplicador de alterações recebe o relatório de um conflito de restrição, ele executa várias ações:

  • Quando o conflito de restrição for um conflito de colisão, o aplicador de alterações determinará se o conflito é novo, temporário ou uma propagação de resolução de mesclagem. Durante o processamento do conflito, o aplicador de alterações pode armazená-lo temporariamente no log de conflitos chamando SaveConstraintConflict (para código gerenciado) ou ISynchronousNotifyingChangeApplierTarget2::SaveConstraintConflict (para código não gerenciado). O aplicador de alterações remove os conflitos temporários do log ao término da sessão de sincronização.

  • Resolve os conflitos de colisão de acordo com a política de resolução de conflitos de colisão definida para a sessão ou de acordo com a ação de resolução de conflitos determinada pelo aplicativo. O aplicativo é chamado para determinar a ação de resolução de conflitos quando a política de resolução de conflitos de colisão é definida como ApplicationDefined (para código gerenciado) ou CCRP_NONE (para código não gerenciado).

  • Resolve os conflitos de restrição de não colisão de acordo com a ação de resolução de conflitos determinada pelo aplicativo. Uma política de resolução de conflitos não pode ser definida para conflitos de restrição de não colisão.

Resolvendo conflitos de restrição

O aplicador de alterações ajuda o provedor de destino a resolver os conflitos de restrição despachando chamadas para o objeto de destino do aplicador de alterações especificado pelo provedor. Quando uma política de resolução de conflitos de colisão é 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 de colisão que ocorrer. Quando a resolução de conflitos de colisão personalizada é especificada, o aplicador de alterações notifica o conflito de colisão ao aplicativo de sincronização, e este especifica a ação de resolução de conflitos. Uma política de resolução de conflitos não pode ser especificada para conflitos de restrição de não colisão. Assim, quando um conflito de restrição de não colisão é relatado, o aplicador de alterações sempre notifica o aplicativo para que este possa especificar a ação de resolução de conflitos. Em todos os casos, 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.

Especificando uma política de resolução de conflitos de colisão

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

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

Código não gerenciado O aplicativo especifica a política usando um mecanismo personalizado, como uma interface personalizada que o aplicativo obtém chamando QueryInterface no objeto do provedor de destino.

O provedor de destino passa a política de resolução de conflitos de colisão para o método ApplyChanges (para código gerenciado) ou ISynchronousNotifyingChangeApplier2::ApplyChanges (para código não gerenciado) do 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 INotifyingChangeApplierTarget2 (para código gerenciado) ou ISynchronousNotifyingChangeApplierTarget2 (para código não gerenciado)

Políticas de resolução de conflitos de colisão para código gerenciado

O Sync Framework define as políticas de resolução de conflitos de colisão a seguir para código gerenciado.

Política de resolução de conflitos

Descrição

SourceWins

A alteração feita na réplica de origem sempre vence. O Sync Framework especifica uma ação de resolução de conflitos SourceWins.

DestinationWins

A alteração feita na réplica de destino sempre vence. O Sync Framework especifica uma ação de resolução de conflitos DestinationWins.

RenameSource

A alteração enviada a partir do provedor de origem é renomeada de forma a não colidir mais com o item conflitante na réplica de destino, e a alteração de origem é aplicada à réplica de destino. O Sync Framework especifica uma ação de resolução de conflitos RenameSource.

RenameDestination

O item conflitante na réplica de destino é renomeado para não colidir mais com a alteração enviada a partir do provedor de origem, e a alteração de origem é aplicada à réplica de destino. O Sync Framework especifica uma ação de resolução de conflitos RenameDestination.

Merge

Os dados do item de origem são combinados com o item de destino. O Sync Framework especifica uma ação de resolução de conflitos Merge.

ApplicationDefined

O aplicador de alterações notifica cada conflito de colisão ao aplicativo de sincronização, à medida que eles ocorrem, usando o evento ItemConstraint. O aplicativo examina os itens conflitantes e especifica a ação de resolução de conflitos chamando SetResolutionAction.

Políticas de resolução de conflitos de colisão para código não gerenciado

O Sync Framework define as políticas de resolução de conflitos de colisão a seguir para código não gerenciado.

Política de resolução de conflitos

Descrição

CCRP_SOURCE_PROVIDER_WINS

A alteração feita na réplica de origem sempre vence. O Sync Framework especifica uma ação de resolução de conflitos SCRA_ACCEPT_SOURCE_PROVIDER.

CCRP_DESTINATION_PROVIDER_WINS

A alteração feita na réplica de destino sempre vence. O Sync Framework especifica uma ação de resolução de conflitos SCRA_ACCEPT_DESTINATION_PROVIDER.

CCRP_RENAME_SOURCE

A alteração enviada a partir do provedor de origem é renomeada para não colidir mais com o item conflitante na réplica de destino, e a alteração de origem é aplicada à réplica de destino. O Sync Framework especifica uma ação de resolução de conflitos SCRA_RENAME_SOURCE.

CCRP_RENAME_DESTINATION

O item conflitante na réplica de destino é renomeado para não colidir mais com a alteração enviada a partir do provedor de origem, e a alteração de origem é aplicada à réplica de destino. O Sync Framework especifica uma ação de resolução de conflitos SCRA_RENAME_DESTINATION.

CCRP_MERGE

Os dados do item de origem são combinados com o item de destino. O Sync Framework especifica uma ação de resolução de conflitos SCRA_MERGE.

CCRP_NONE

O aplicador de alterações notifica cada conflito de colisão ao aplicativo de sincronização, à medida que eles ocorrem, usando o evento ISyncConstraintCallback::OnConstraintConflict. O aplicativo examina os itens conflitantes e especifica a ação de resolução de conflitos chamando IConstraintConflict::SetConstraintResolveActionForChange ou IConstraintConflict::GetConstraintResolveActionForChangeUnit.

Especificando resoluções de conflitos personalizadas

Um aplicativo pode indicar que ele especificará uma ação de resolução de conflitos para cada conflito de restrição que ocorrer. Para isso, o aplicativo se registra para receber notificações de conflitos de restrição. Quando um conflito de restrição é relatado, o Sync Framework notifica o aplicativo. O aplicativo pode então analisar o conflito e definir a ação de resolução de conflitos desejada.

Especificando resoluções de conflitos personalizadas usando código gerenciado

Para receber notificação de conflitos de colisão, um aplicativo executa as ações a seguir antes de iniciar a sincronização.

Se o aplicativo tiver executado essas etapas, o aplicador de alterações irá gerar o evento ItemConstraint uma vez para cada conflito de restrição de colisão relatado durante a sincronização.

Como não é possível especificar uma política de resolução para conflitos de restrição de não colisão, o aplicador de alterações também gera o evento ItemConstraint uma vez para cada conflito de restrição de não colisão que é relatado.

O manipulador do evento ItemConstraint recebe um objeto ItemConstraintEventArgs que contém metadados e dados de item das duas alterações no conflito. O manipulador de eventos 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. O aplicador de alterações então processa o conflito e despacha a chamada apropriada para o objeto de destino do aplicador de alterações. Esteja ciente de que, quando o conflito de restrição não for uma colisão, as únicas ações de resolução de conflitos válidas serão SaveConflict e SkipChange.

O Sync Framework fornece o conjunto de ações de resolução de conflitos de restrição 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

Válido para tipo de conflito

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 e especifica uma ação de salvamento DeleteConflictingAndSaveSourceItem. A alteração de origem é aplicada à réplica de destino e o item de destino conflitante é excluído da réplica de destino.

Apenas conflitos de colisão.

DestinationWins

A alteração feita na réplica de destino vence. O aplicador de alterações passa a alteração de origem para o método SaveItemChange e especifica uma ação de salvamento DeleteAndStoreTombstone. O provedor de destino cria uma marca de exclusão para a alteração de origem. Quando o destino agir como a origem em uma sincronização posterior, ele irá enumerar uma alteração que represente a exclusão do item de origem, removendo-o assim da comunidade de sincronização.

Apenas conflitos de colisão.

RenameSource

A alteração enviada a partir do provedor de origem é renomeada para não colidir mais com o item conflitante na réplica de destino, e a alteração de origem é aplicada à réplica de destino. O aplicador de alterações passa a alteração para o método SaveItemChange e especifica uma ação de salvamento RenameSourceAndUpdateVersionAndData.

Apenas conflitos de colisão.

RenameDestination

O item conflitante na réplica de destino é renomeado para não colidir mais com a alteração enviada a partir do provedor de origem, e a alteração de origem é aplicada à réplica de destino. O aplicador de alterações passa a alteração para o método SaveItemChange e especifica uma ação de salvamento RenameDestinationAndUpdateVersionData.

Apenas conflitos de colisão.

Merge

Os dados do item de origem são combinados com o item de destino. O aplicador de alterações passa os dados de alteração da réplica de origem para o método SaveItemChange e especifica uma ação de salvamento ChangeIdUpdateVersionAndMergeData. Para obter detalhes, consulte Mesclando itens conflitantes, abaixo.

Apenas conflitos de colisão.

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 SaveConstraintConflict, 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.

Todos os conflitos de restrição.

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.

Todos os conflitos de restrição.

Especificando resoluções de conflitos personalizadas usando código não gerenciado

Para receber notificação de conflitos de colisão, um aplicativo executa as ações a seguir antes de iniciar a sincronização.

Se o aplicativo tiver executado essas etapas, o aplicador de alterações chamará o método OnConstraintConflict uma vez para cada conflito de restrição de colisão relatado durante a sincronização.

Como não é possível especificar uma política de resolução para conflitos de restrição de não colisão, o aplicador de alterações também chama o método OnConstraintConflict uma vez para cada conflito de restrição de não colisão que é relatado.

O método OnConstraintConflict recebe um objeto IConstraintConflict que contém metadados e dados de item das duas alterações em conflito. O método 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 IConstraintConflict::SetConstraintResolveActionForChange ou IConstraintConflict::GetConstraintResolveActionForChangeUnit. O aplicador de alterações então processa o conflito e despacha a chamada apropriada para o objeto de destino do aplicador de alterações. Esteja ciente de que, quando o conflito de restrição não for uma colisão, as únicas ações de resolução de conflitos válidas serão SCRA_TRANSFER_AND_DEFER e SCRA_DEFER.

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

Política de resolução de conflitos

Descrição

Válido para tipo de conteúdo

SCRA_ACCEPT_SOURCE_PROVIDER

A alteração feita na réplica de origem sempre vence. O aplicador de alterações passa a alteração para o método ISynchronousNotifyingChangeApplierTarget::SaveChange e especifica uma ação de salvamento SSA_DELETE_CONFLICTING_AND_SAVE_SOURCE_ITEM. A alteração de origem é aplicada à réplica de destino e o item de destino conflitante é excluído da réplica de destino.

Apenas conflitos de colisão.

SCRA_ACCEPT_DESTINATION_PROVIDER

A alteração feita na réplica de destino sempre vence. O aplicador de alterações passa a alteração de origem para o método SaveChange e especifica uma ação de salvamento SSA_DELETE_AND_STORE_TOMBSTONE. O provedor de destino cria uma marca de exclusão para a alteração de origem. Quando o destino agir como a origem em uma sincronização posterior, ele irá enumerar uma alteração que represente a exclusão do item de origem, removendo-o assim da comunidade de sincronização.

Apenas conflitos de colisão.

SCRA_RENAME_SOURCE

A alteração enviada a partir do provedor de origem é renomeada para não colidir mais com o item conflitante na réplica de destino, e a alteração de origem é aplicada à réplica de destino. O aplicador de alterações passa a alteração para o método SaveChange e especifica uma ação de salvamento SSA_RENAME_SOURCE_AND_UPDATE_VERSION_AND_DATA.

Apenas conflitos de colisão.

SCRA_RENAME_DESTINATION

O item conflitante na réplica de destino é renomeado para não colidir mais com a alteração enviada a partir do provedor de origem, e a alteração de origem é aplicada à réplica de destino. O aplicador de alterações passa a alteração para o método SaveChange e especifica uma ação de salvamento SSA_RENAME_DESTINATION_AND_UPDATE_VERSION_AND_DATA.

Apenas conflitos de colisão.

SCRA_MERGE

Os dados do item de origem são combinados com o item de destino. O aplicador de alterações passa os dados de alteração da réplica de origem para o método SaveChange e especifica uma ação de salvamento SSA_CHANGE_ID_UPDATE_VERSION_AND_MERGE_DATA. Para obter detalhes, consulte Mesclando itens conflitantes, abaixo.

Apenas conflitos de colisão.

SCRA_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 ISynchronousNotifyingChangeApplierTarget2::SaveConstraintConflict, 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.

Todos os conflitos de restrição.

SCRA_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.

Todos os conflitos de restrição.

Mesclando itens conflitantes

A mesclagem de dois itens em um conflito de restrição de colisão é diferente da mesclagem de itens em um conflito de simultaneidade, pois as IDs dos dois itens envolvidos em um conflito de colisão são diferentes. Por exemplo, um arquivo chamado "LivrosFavoritos.txt" é criado em uma réplica e recebe uma ID de item id1. Um arquivo chamado "LivrosFavoritos.txt" também é criado em outra réplica e recebe uma ID id2. Quando as réplicas são sincronizadas, o Sync Framework trata esses dois itens como sendo diferentes, porque eles têm IDs diferentes, mas a réplica de destino os trata como o mesmo item, pois eles têm o mesmo nome. Assim, o provedor de destino relata um conflito de colisão e especifica que o conteúdo dos dois itens deve ser mesclado. O aplicador de alterações atribui ao item mesclado uma ID id1 e especifica que a réplica de destino deve armazenar uma marca de exclusão de mesclagem para id2.

Quando um conflito de colisão é resolvido por meio de mesclagem, é necessário selecionar uma das IDs de item como a ID vencedora que é atribuída ao item mesclado, e controlar adequadamente se a ID de item perdedora foi mesclada. O aplicador de alterações seleciona a ID de item vencedora comparando as duas IDs de item e selecionando a ID menor como a vencedora. A ID de item vencedora é usada para identificar o item mesclado na réplica de destino. Uma marca de exclusão de mesclagem é criada e armazenada na réplica de destino. A marca de exclusão de mesclagem controla se a ID de item perdedora identifica o mesmo item que a ID de item vencedora na comunidade de sincronização. Os metadados de uma marca de exclusão de mesclagem são iguais aos de uma marca de exclusão de item excluído, com a adição da ID de item vencedora.

Código gerenciado Quando a ação de resolução de alteração for Merge, o aplicador de alterações chamará SaveItemChange e especificará uma ação de salvamento ChangeIdUpdateVersionAndMergeData. O aplicador de alterações passa a alteração com a ID de item perdedora como o parâmetro change. A alteração com a ID de item vencedora pode ser obtida com a chamada do método GetWinnerChange()()()() do objeto SaveChangeContext passado no parâmetro context.

Código não gerenciado Quando a ação de resolução de alteração for SCRA_MERGE, o aplicador de alterações chamará ISynchronousNotifyingChangeApplierTarget::SaveChange e especificará uma ação de salvamento SSA_CHANGE_ID_UPDATE_VERSION_AND_MERGE_DATA. O aplicador de alterações passa a alteração com a ID de item perdedora como o parâmetro pChange. A alteração com a ID de item vencedora pode ser obtida com a chamada do método ISaveChangeContext2::GetWinnerChange do objeto ISaveChangeContext2 passado no parâmetro pSaveContext.

O provedor de destino deve executar várias etapas para processar a ação de mesclagem corretamente. Considere uma ação de mesclagem que especifica id1 como a ID de item perdedora e id2 como a ID de item vencedora. O provedor de destino deve executar as etapas a seguir em uma transação.

  1. Armazenar uma marca de exclusão de mesclagem nos metadados de destino. Essa marca contém id1 como a ID de item perdedora e id2 como a ID de item vencedora. Se já existir uma marca de exclusão de mesclagem na réplica de destino que contém id1 como a ID de item perdedora e outra ID de item, id3, como a ID de item vencedora, o provedor executará as etapas a seguir.

    1. Se id2 for maior que id3, o provedor criará e armazenará duas marcas de exclusão de mesclagem. Uma dessas marcas contém id1 como a ID de item perdedora e id2 como a ID de item vencedora. A outra marca contém id2 como a ID de item perdedora e id3 como a ID de item vencedora. Essa segunda marca de exclusão de mesclagem pode já existir e, nesse caso, ela é simplesmente mantida. Dessa maneira, é criada uma cadeia de marcas de exclusão de mesclagem, por ordem decrescente de ID de item.

    2. Se id3 for maior que id2, o provedor retornará um erro.

  2. Mescla os dados do item na réplica de destino com os dados do item do provedor de origem. O item de destino pode ser identificado por id1 ou id2.

  3. Aplica os metadados para a alteração aos metadados de destino e os dados mesclados para a alteração ao repositório de itens de destino, usando a ID de item vencedora, id2, como a ID de item da alteração mesclada. Os metadados da alteração podem ser obtidos com a chamada do método GetWinnerChange()()()()context (para código gerenciado) ou o método GetWinnerChangepContext (para código não gerenciado).

Propagando um item mesclado

A propagação de itens mesclados de um conflito de restrição de colisão difere da propagação de itens mesclados de um conflito de simultaneidade, pois os conflitos podem ocorrer com a ID de item vencedora, a ID de item perdedora ou ambas. Por exemplo, a réplica X contém um item com uma ID id1 que foi mesclado a partir de itens com as IDs id1 e id2. A réplica Y contém um item com uma ID id2 e fez alterações locais no item. Quando o item mesclado identificado por id1 é enviado da réplica X para a réplica Y, surge um conflito, pois id1 agora se refere ao mesmo item que id2.

O aplicador de alterações ajuda o provedor de destino a aplicar uma alteração de item mesclado detectando conflitos de simultaneidade que ocorrem com a ID de item vencedora e com a ID de item perdedora, e determinando a ação correta que o provedor de destino deve executar para aplicar a alteração de item mesclado à réplica de destino. Se o provedor de destino detectar um conflito de restrição ao aplicar uma alteração de item mesclado, ele deverá relatar o conflito de restrição da mesma maneira que outros conflitos de restrição.

O aplicador de alterações também detecta quando a réplica de origem e a réplica de destino discordam sobre a identidade de um item. Por exemplo, a réplica X resolve um conflito de colisão entre itens com as IDs id1 e id2 mesclando os itens e atribuindo id1 ao item mesclado. A réplica Y resolve um conflito de colisão entre itens com as IDs id1 e id2 renomeando o item identificado por id1 e mantendo ambos os itens. A réplica X envia o item mesclado identificado por id1 e uma marca de exclusão de mesclagem que indica que id2 foi mesclado em id1. O conflito em id1 é detectado e resolvido como um conflito de simultaneidade. O conflito em id2 é detectado e relatado para o aplicativo de sincronização como um conflito de identidade, especificando o motivo do conflito como Identity (para código gerenciado) ou CCR_IDENTITY (para código não gerenciado). O aplicativo determina se o conflito deve ser resolvido com a manutenção da alteração de origem ou da alteração de destino.

Lembre-se de que, quando o provedor de origem usa filtragem de unidade de alteração e o provedor de destino não é filtrado, às vezes pode ocorrer um conflito de identidade mesmo quando o item identificado pela marca de exclusão de mesclagem deve ser removido da réplica de destino. Isso acontece devido à maneira como o conhecimento filtrado é manipulado pelo aplicador de alteração. Para garantir sincronização e propagação apropriadas da marca de exclusão de mesclagem, o provedor de destino deve manter a marca de exclusão de mesclagem e remover o item conflitante da réplica de destino.

Quando uma alteração de item mesclado é enviada pelo provedor de origem, o aplicador de alterações determina a ação correta que o provedor de destino deve executar para aplicar a alteração à réplica de destino. A tabela a seguir lista as ações de salvamento que o aplicador de alterações pode especificar, bem como as ações que o provedor deve executar para aplicar a alteração.

Ação de salvamento

Ações do provedor

ChangeIdUpdateVersionAndSaveData (para código gerenciado), SSA_CHANGE_ID_UPDATE_VERSION_AND_SAVE_DATA (para código não gerenciado)

Armazenar uma marca de exclusão de mesclagem para a ID de item perdedora, seguindo as mesmas etapas descritas em Mesclando itens conflitantes, acima. Aplicar a alteração do item vencedor.

ChangeIdUpdateVersionOnly (para código gerenciado), SSA_CHANGE_ID_UPDATE_VERSION_ONLY (para código não gerenciado)

Armazenar uma marca de exclusão de mesclagem para a ID de item perdedora, seguindo as mesmas etapas descritas em Mesclando itens conflitantes, acima. Aplicar somente metadados para a alteração de item vencedor.

ChangeIdUpdateVersionAndDeleteAndStoreTombstone (para código gerenciado), SSA_CHANGE_ID_UPDATE_VERSION_AND_DELETE_AND_STORE_TOMBSTONE (para código não gerenciado)

Armazenar uma marca de exclusão de mesclagem para a ID de item perdedora, seguindo as mesmas etapas descritas em Mesclando itens conflitantes, acima. Excluir o item identificado pela ID de item vencedora e armazenar uma marca de exclusão para ele.

StoreMergeTombstone (para código gerenciado), SSA_STORE_MERGE_TOMBSTONE (para código não gerenciado)

Armazenar uma marca de exclusão de mesclagem para a ID de item perdedora, seguindo as mesmas etapas descritas em Mesclando itens conflitantes, acima.

Dica

Todas as etapas de uma ação de salvamento devem ser aplicadas como uma ação atômica.

Consulte também

Referência

SaveChangeContext

SaveChangeWithChangeUnitsContext

NotifyingChangeApplier

INotifyingChangeApplierTarget2

Outros recursos

Manipulando conflitos

Detectando e solucionando conflitos de simultaneidade

Interface ISaveChangeContext2

Interface ISaveChangeWithChangeUnitsContext2

Interface ISynchronousNotifyingChangeApplier2

Interface ISynchronousNotifyingChangeApplierTarget2