Como a replicação de mesclagem detecta e soluciona conflitos

A replicação de mesclagem permite que diversos nós façam alterações independentes nos dados, portanto existirão situações em que uma alteração feita em um nó pode entrar em conflito com uma alteração feita nos mesmos dados em outro nó. Em outras situações, o Merge Agent encontra um erro como uma violação de restrição e não consegue propagar uma alteração feita em um determinado nó para outro nó. Este tópico descreve tipos de conflitos, como os conflitos são detectados e solucionados, e fatores que afetam a detecção e resolução.

Detectando e solucionando conflitos

O Merge Agent detecta os conflitos usando a coluna linhagem da tabela do sistema MSmerge_contents. Se um rastreamento feito no nível de coluna for habilitado para um artigo, a coluna COLV1 também será utilizada. Estas colunas contêm metadados sobre quando uma linha ou coluna é inserida ou atualizada e sobre quais nós em uma topologia de replicação de mesclagem fizeram alterações na linha ou coluna. Você pode usar o procedimento armazenado sp_showrowreplicainfo (Transact-SQL) para exibir este metadados.

À medida que o Merge Agent enumera as alterações que serão aplicadas durante a sincronização, ele compara os metadados de cada linha no Publicador e no Assinante. O Merge Agent usa estes metadados para determinar se uma linha ou coluna foi alterada em mais de um nó da topologia, o que indica um conflito potencial. Após a detecção de um conflito, o Merge Agent inicia o solucionador de conflito especificado para o artigo com conflito e usa o solucionador para determinar o vencedor do conflito. A linha vencedora é aplicada ao Publicador e ao Assinante e os dados da linha perdedora são gravados em uma tabela de conflitos.

Os conflitos são solucionados automaticamente e imediatamente pelo Merge Agent, a menos que você tenha escolhido a solução de conflitos interativa para o artigo. Para obter mais informações, consulte Resolução de conflito interativo. Se você alterar manualmente a linha vencedora de um conflito usando a replicação de mesclagem Conflict Viewer, o Merge Agent aplicará a versão vencedora da linha ao servidor perdedor durante a próxima sincronização.

Registro de conflitos solucionados

Depois do Merge Agent solucionar o conflito de acordo com a lógica do solucionador de conflitos, ele registra os dados do conflito selecionado de acordo com o tipo de conflito.

  • Para os conflitos UPDATE e INSERT, ele grava a versão perdedora da linha na tabela de conflitos do artigo, que recebe o nome no formato conflict_<Nome_da_Publicação>_<Nome_do_Artigo>. A informações gerais sobre conflitos, como o tipo de conflito, são gravadas na tabela MSmerge_conflicts_info.

  • Para os conflitos DELETE, ele grava a versão perdedora da linha na tabelaMSmerge_conflicts_info. Quando um excluir perde para um atualizar, não haverá dados para uma linha perdedora (porque ela era um excluir), assim, nada é gravado em conflict_<Nome_da_Publicação>_<Nome_do_Artigo>.

As tabelas de conflito de cada artigo são criadas no banco de dados de publicação, banco de dados de assinatura ou ambos (o padrão), dependendo do valor especificado do parâmetro @conflict_logging do sp_addmergepublication. Cada tabela de conflitos tem a mesma estrutura do artigo no qual ela é baseada, com a adição da coluna origin_datasource_id. O Merge Agent exclui os dados da tabela de conflitos se eles forem mais antigos do que o período de retenção de conflitos da publicação, que é especificado usando o parâmetro @conflict_retention do sp_addmergepublication (o padrão é 14 dias).

A replicação fornece o Visualizador de Conflitos de Replicação e os procedimentos armazenados (sp_helpmergearticleconflicts, sp_helpmergeconflictrowse sp_helpmergedeleteconflictrows) para exibir dados do conflito. Para obter mais informações, consulte Como exibir e resolver conflitos de dados para publicações de mesclagem (SQL Server Management Studio) e Como exibir informações sobre conflitos para publicações de mesclagem (Programação Transact-SQL de replicação).

Fatores que afetam solução de conflitos

Há dois fatores que afetam como o Merge Agent soluciona um conflito que detectou:

  • O tipo de assinatura: cliente ou servidor (seja a assinatura pull ou push, isso não afeta a solução de conflitos).

  • O tipo de rastreamento de conflitos usado: no nível de linha, de coluna ou no nível de registro lógico.

Tipos de assinatura

Ao criar uma assinatura, além de especificar se é uma assinatura push ou pull, você especifica se é uma assinatura de cliente ou servidor. Depois da criação de uma assinatura, o tipo não pode ser alterado (nas versões anteriores do Microsoft SQL Server, as assinaturas de cliente e servidor eram citadas respectivamente como local e global).

Uma assinatura com valor de prioridade atribuído (de 0.00 a 99.99) é chamada de assinatura de servidor; uma assinatura que usa o valor de prioridade do Publicador é chamada de assinatura de cliente. Além disso, os Assinantes com assinatura de servidor pode republicar dados em outros Assinantes. A tabela a seguir resume as principais diferenças e utilizações de cada tipo de Assinante.

Tipo

Valor de prioridade

Usado

Servidor

Atribuído por usuário

Quando você quiser que diferentes Assinantes tenham prioridades diferentes.

Cliente

0.00, mas alterações de dados assumem o valor de prioridade do Publicador depois da sincronização

Quando você quiser que todos os Assinantes tenham a mesma prioridade e que o primeiro Assinante mescle com o Publicador para vencer o conflito.

Se uma linha for alterada em uma assinatura de cliente, nenhuma prioridade será atribuída à alteração até a assinatura ser sincronizada. Durante a sincronização, as alterações do Assinante recebem a prioridade do Publicador e retêm essa prioridade para sincronizações subseqüentes. De certo modo, o Publicador assume a propriedade da alteração. Este comportamento permite que o primeiro Assinante sincronize com o Publicador para vencer os conflitos subseqüentes com outros Assinantes de uma determinada linha ou coluna.

Ao alterar uma linha em uma assinatura de servidor, a prioridade da assinatura será armazenada nos metadados da alteração. Este valor de prioridade se desloca com a linha alterada, à medida que ele mescla com as alterações em outros Assinantes. Isto assegura que uma alteração feita por uma assinatura com prioridade superior não perca para uma alteração subseqüente feita por uma assinatura com prioridade inferior.

Uma assinatura não pode ter um valor de prioridade explícito mais alto do que seu Publicador. O Publicador de alto nível em uma topologia de replicação de mesclagem sempre tem um valor de prioridade explícito de 100.00. Todas as assinaturas dessa publicação devem ter um valor de prioridade menor do que este valor. Em uma topologia de republicação:

  • Se o assinante estiver republicando dados, a assinatura deverá ser de servidor com valor de prioridade menor do que o do Publicador acima do Assinante.

  • Se o assinante não estiver republicando dados (porque ele está no nível de folha da árvore de replicação), a assinatura deverá ser de cliente.

Para obter mais informações sobre assinaturas e prioridades, consulte Exemplo de solução de conflito de mesclagem baseado em tipo de assinatura e prioridades atribuídas.

Notificação de conflito atrasada

A notificação de conflito atrasada pode acontecer com assinaturas de servidor que têm prioridades de conflitos diferentes. Considere o seguinte cenário, no qual as alterações não conflitantes são trocadas entre o Publicador e um Assinante de prioridade inferior, que resulta em alterações conflitantes quando um Assinante de prioridade superior sincronizar com o Publicador:

  1. O Publicador e um Assinante de baixa prioridade, chamado de LowPrioritySub, trocam alterações sobre diversas sincronizações sem conflito.

  2. Um assinante de prioridade mais alta, chamado HighPrioritySub, não foi sincronizado com o Publicador em alguma momento e fez alterações às mesmas linhas que o Assinante LowPrioritySub efetuou.

  3. O Assinante HighPrioritySub sincroniza com o Publicador e vence o conflito entre suas alterações e o Assinante LowPrioritySub porque ele tem uma prioridade mais alta do que o Assinante LowPrioritySub. O Publicador agora contém as alterações feitas pelo Assinante HighPrioritySub.

  4. O Assinante LowPrioritySub mescla em seguida com o Publicador e baixa um grande número de alterações por causa dos conflitos com o Assinante LowPrioritySub.

Esta situação pode se tornar problemática quando o Assinante de prioridade mais baixa fez alterações às mesmas linhas que agora são perdedoras do conflito. Isto pode resultar em uma perda de todas as alterações feitas por este Assinante. Uma solução potencial para este problema é certificar que todos os Assinantes tenham a mesma prioridade, a menos que a lógica do negócio indique o contrário.

Nível de rastreamento

Se uma alteração de dados se qualifica ou não como conflito, isto dependerá do tipo de rastreamento de conflitos definido para um artigo: nível de linha, nível de coluna ou nível de registro lógico. Para obter mais informações sobre rastreamento de nível de registro lógico, consulte Detectando e resolvendo conflitos em registros lógicos.

Quando os conflitos forem reconhecidos em nível de linha, as alterações feitas às linhas correspondentes serão consideradas como um conflito, sendo efetuadas ou não na mesma coluna. Por exemplo, suponha que uma alteração seja feita na coluna de endereço de uma linha de Publicador e uma segunda alteração seja feita na coluna do número de telefone da linha do Assinante correspondente (na mesma tabela). Com o rastreamento de nível de linha, um conflito é detectado porque alterações foram feitas à mesma linha. Com o rastreamento de nível de coluna, nenhum conflito é detectado porque as alterações foram feitas em colunas diferentes na mesma linha.

Para o rastreamento de nível de coluna e de linha, a solução do conflito é a mesma: toda a linha de dados é sobrescrita pelos dados do vencedor do conflito (para ao rastreamento de nível de registro lógico, a solução depende da propriedade do artigological_record_level_conflict_resolution).

As semânticas do aplicativo normalmente determinam qual opção de rastreamento usar. Por exemplo, se você estiver atualizando dados do cliente, geralmente inseridos ao mesmo tempo, como endereço e número de telefone, deve ser escolhido o rastreamento de nível de linha. Se o rastreamento de nível de coluna foi escolhido nesta situação, as alterações no número de telefone em um local e no endereço do cliente em outro local não seriam detectadas como conflito: os dados seriam mesclados na sincronização e o erro seria omitido. Em outras situações, a atualização de colunas individuais de sites diferentes pode ser a escolha mais lógica. Por exemplo, dois sites podem ter acesso a diferentes tipos de informações sobre estatística de um cliente, como nível de receita e quantidade total de dólares das compras com cartões de crédito. A seleção do rastreamento de nível de coluna assegura que ambos os sites possam inserir os dados estatísticos para colunas diferentes sem gerar conflitos desnecessários.

ObservaçãoObservação

Se o seu aplicativo não exigir o rastreamento de nível de coluna, será recomendado que você use o rastreamento de nível de linha (o padrão) porque normalmente ele resulta em um melhor desempenho da sincronização. Se o rastreamento de linha for usado, a tabela base poderá incluir no máximo 1.024 colunas, mas as colunas devem ser filtradas do artigo de modo que sejam publicadas 246 colunas, no máximo. Se rastreamento de coluna for usado, a tabela base poderá incluir no máximo 246 colunas.

Tipos de conflitos

Embora a maioria dos conflitos estejam relacionados às atualizações (uma atualização em um nó entra em conflito com uma atualização ou exclusão em outro nó), existem outros tipos de conflitos. Cada tipo de conflito discutido nesta seção pode ocorrer durante a fase de carregamento ou de download do processamento de mesclagem. O processamento do carregamento é a primeira reconciliação das alterações efetuadas em uma determinada sessão de mesclagem, e é a fase durante a qual o Merge Agent replica as alterações do Assinante para o Publicador. Os conflitos detectados durante este processamento são chamados de conflitos de carregamento. O processamento de download envolve mover as alterações do Publicador para o Assinante e ocorre depois do processamento de carregamento. Os conflitos durante esta fase de processamento são chamado de conflitos de download.

Para obter mais informações sobre tipos de conflito, consulte MSmerge_conflicts_info (Transact-SQL), principalmente as colunas conflict_type e reason_code.

Conflitos do tipo Update-Update

O Merge Agent detecta os conflitos do tipo update-update quando uma atualização em uma linha (coluna ou registro lógico) em um nó entra em conflito com outra atualização na mesma linha em outro nó. O comportamento do solucionador padrão neste caso é enviar a versão vencedora da linha ao nó perdedor, e registrar a versão da linha perdedora na tabela de conflitos do artigo.

Conflitos do tipo Update-Delete

O Merge Agent detecta os conflitos do tipo update-delete quando uma atualização de dados em um nó, entra em conflito com uma exclusão em outro. Neste caso, o Merge Agent atualiza uma linha. No entanto, quando o Merge Agent procura essa linha no destino, ele não consegue encontrar a linha porque ela foi excluída. Se o vencedor for o nó que atualizou a linha, a exclusão do nó perdedor é descartada e o Merge Agent envia a linha recém-atualizada para o perdedor do conflito. O Merge Agent registra as informações sobre a versão perdedora da linha na tabelaMSmerge_conflicts_info.

Conflitos de alteração com falha

O Merge Agent eleva estes conflitos quando não puder aplicar uma determinada alteração. Isto normalmente ocorre por causa de uma diferença nas definições de restrições entre o Publicador e o Assinante, e o uso da propriedade NOT FOR REPLICATION (NFR) na restrição. Os exemplos incluem:

  • Um conflito de chave estrangeira no Assinante, que pode acontecer quando a restrição do lado do Assinante não estiver marcada como NFR.

  • As diferenças em restrições entre o Publicador e os Assinantes, e as restrições não são marcadas como NFR.

  • Indisponibilidade de objetos dependentes no Assinante. Por exemplo, se você publicar uma exibição, mas não a tabela da qual essa exibição depende, ocorrerá uma falha se você tentar inserir por meio dessa exibição no Assinante.

  • Lógica de filtragem de junção de uma publicação que não corresponde às restrições de chave primária e chave estrangeira. Podem ocorrer conflitos quando o mecanismo relacional SQL Server tenta honrar uma restrição, mas o Merge Agent está honrando a definição do filtro de junção entre os artigos. O Merge Agent não consegue aplicar a alteração no nó de destino por causa das restrições de nível de tabela, que resultam em um conflito.

  • Devido às violações no índice exclusivo, na restrição exclusiva ou na chave primária poderão ocorrer conflitos se as colunas de identidade estiverem definidas para o artigo e o gerenciamento automatizado de identidade não for usado. Isto poderá ser um problema se dois Assinantes precisarem usar o mesmo valor de identidade para uma linha inserida recentemente. Para obter mais informações sobre o gerenciamento de intervalo de identidade, consulte Colunas de identidade de replicação.

  • Conflitos devido à lógica de gatilho que impede o Merge Agent de inserir uma linha na tabela de destino. Considere um gatilho de atualização definido no Assinante; o gatiho não fica marcado como NFR e inclui um ROLLBACK em sua lógica. Se ocorrer uma falha, o gatilho emitirá um ROLLBACK da transação, que como conseqüência faz o Merge Agent detectar um conflito de alteração com falha.