Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A partir do SQL Server 2019 (15.x) CU13, você pode configurar a replicação ponto a ponto para resolver conflitos automaticamente, permitindo que a inserção ou atualização mais recente vença o conflito. Se qualquer gravação excluir a linha, o SQL Server permitirá que a exclusão ganhe o conflito. Este método é conhecido como last write wins.
Use procedimentos armazenados para configurar as últimas vitórias de gravação. Não use o Assistente de Topologia Ponto a Ponto para adicionar ou remover nós quando usar o último gravador.
Considerações importantes sobre configuração
Observação
Depois de atualizar para o SQL Server 2019 (15.x) CU13 ou uma versão posterior, quando você configura uma publicação com resolução de conflitos definida como últimas vitórias de gravação, metadados adicionais são incluídos na publicação. Se, posteriormente, você desinstalar/fazer downgrade para uma versão anterior ao SQL Server 2019 (15.x) CU13, esses metadados extras causarão problemas. Você deve descartar essas publicações antes de fazer o downgrade e, em seguida, recriá-las na versão inferior.
Ao configurar a replicação ponto a ponto com deteção e resolução automática de conflitos para resolver como vitória na última gravação, inclua as seguintes configurações e configurações:
Crie a publicação com os seguintes parâmetros,
Definido
@p2p_conflictdetection_policy = 'lastwriter'para especificar as últimas vitórias de gravação. Ver sp_addpublication (Transact-SQL). Este parâmetro é introduzido no SQL Server 2019 (15.x) CU13. O valororiginatoridpadrão resolve conflitos com base na ID do originador e é o mesmo que a resolução de conflitos antes do SQL Server 2019 (15.x) CU13.Definido
@p2p_continue_onconflict = 'true'para permitir que o agente de distribuição resolva o conflito.
Ao adicionar o artigo (
sp_addarticle), confirme o comportamento do tipo de comando para o comando update (@upd_cmd). As opções incluem:-
CALL(Padrão) SCALL
Veja detalhes em sp_addarticle.
-
Quando você adiciona um artigo (
sp_addarticle) em uma publicação com uma política de deteção de conflito do último gravador, o usoCALLouSCALLcomo tipo de comando para@upd_cmdo parâmetroCALLé padrão.Observação
O SQL Server oferece suporte
SCALLpara@upd_cmd. ComSCALLo , quando uma transação atualiza um valor para o mesmo valor, ela não é considerada como uma alteração eSCALLo formato não fornece o valor para colunas que não são atualizadas ou modificadas. Para obter mais informações sobre o formato de chamada SCALL, consulte Sintaxe de chamada para procedimentos armazenados.Você pode usar a publicação ponto a ponto com a deteção e resolução de conflitos do último gravador em um grupo de disponibilidade. See:
Você pode ver o conflito e sua resolução.
- No SQL Server Management Studio, clique com o botão direito do mouse na publicação e selecione Exibir Conflitos.
Ou
- Consulta
conflict_schemaname_tablenamena base de dados de publicações. Por exemplo,conflict_dbo_tab1. Consulte conflict_<schema>_<table> (Transact-SQL).
Os conflitos de inserção e atualização são resolvidos com base no último gravador, mas a exclusão sempre prevalece. Por exemplo, se você tiver um conflito de exclusão-atualização e a atualização tiver sido feita posteriormente, a exclusão ainda vencerá.
A deteção e resolução de conflitos do último gravador é determinada com base em uma coluna
$sys_mw_cd_idoculta. O tipo de dados desta coluna é datetime2.
Comparação de deteção de conflitos
A tabela a seguir compara como os conflitos são detetados e resolvidos com a replicação ponto a ponto tradicional e quando a resolução de conflitos do último gravador está habilitada:
| Tipo de conflito | Detalhes do conflito | Ponto a ponto | Último escritor |
|---|---|---|---|
| Insert-Insert | Todas as linhas em cada tabela que participam da replicação ponto a ponto são identificadas exclusivamente usando valores de chave primária. Um conflito de inserção-inserção ocorre quando uma linha com o mesmo valor de chave foi inserida em mais de um nó. | Se a linha de entrada for a vencedora, atualizaremos a linha de destino. Em ambos os casos, registamos a informação. | Se a linha de entrada for a vencedora, atualizaremos a linha de destino. Em ambos os casos, registamos a informação. |
| Update-Update | Ocorre quando a mesma linha foi atualizada em mais de um nó. | Se a linha de entrada for a vencedora, modificaremos APENAS as colunas alteradas. | Se a linha de entrada for a vencedora, modificaremos todas as colunas no destino (se @upd_cmd estiver definido como default – CALL). |
| Update-Insert | Ocorre se uma linha foi atualizada em um nó, mas a mesma linha foi excluída e, em seguida, reinserida em outro nó. | Se a linha de entrada for a vencedora, modificaremos APENAS as colunas alteradas. | Isso ocorre quando uma linha é atualizada peer1 e a mesma linha é excluída e reinserida no peer2. Quando a sincronização ocorre, a linha em peer1 é excluída como excluir sempre ganha e, em seguida, a mesma linha é inserida, enquanto a linha é atualizada como peer2 a atualização aconteceu em um momento posterior. Isto conduz à não convergência. |
| Inserir- Atualizar | Ocorre se uma linha foi excluída e, em seguida, reinserida em um nó e a mesma linha foi atualizada em outro nó. | Se a linha de entrada for a vencedora, atualizaremos todas as colunas. | Isso ocorre quando uma linha é excluída e reinserida e peer1 a mesma linha é atualizada no peer2. Quando a sincronização ocorre, a linha é excluída, pois peer2 a exclusão sempre vence e, em seguida, é inserida novamente. No peer1, a atualização é ignorada. |
| Delete-Insert Insert-Delete |
Ocorre se uma linha foi excluída em um nó, mas a mesma linha foi excluída e, em seguida, reinserida em outro nó. | Atualmente, pensamos que isso é um conflito D-U e, se a linha de entrada for vencedora, excluiremos a linha do destino. | Isso ocorre quando uma linha é excluída e peer1 a mesma linha é excluída + reinserida no peer2. Quando a sincronização ocorre, a linha em peer2 é excluída, enquanto a linha é inserida em peer1. Isso ocorre porque não armazenamos informações sobre a linha excluída, portanto, não sabemos se a linha foi excluída ou não estava presente no par. Isto conduz à não convergência. |
| Delete-Update | Ocorre se uma linha foi excluída em um nó, mas a mesma linha foi atualizada em outro nó. | Atualmente, pensamos que isso é um conflito D-U e, se a linha de entrada for a vencedora, excluiremos a linha do destino. | Este é um conflito D-U. Como a exclusão sempre ganha, a exclusão de entrada é a vencedora e nós excluímos a linha do destino. |
| Update-Delete | Ocorre se uma linha foi atualizada em um nó, mas a mesma linha foi excluída em outro nó. | No procedimento armazenado de atualização ponto a ponto, se houver um conflito U-D, imprimimos a seguinte mensagem e não a resolvemos.An update-delete conflict was detected and unresolved. The row could not be updated since the row does not exist. |
Este é um conflito U-D. Como a exclusão sempre vence, a atualização de entrada é ignorada. |
| Delete-Delete | Ocorre quando uma linha foi excluída em mais de um nó. | No procedimento armazenado peer-to-peer Delete, se houver conflito D-D, não processamos nenhuma alteração, apenas a registramos. | Se houver conflito D-D, então não processamos nenhuma alteração, apenas a registramos. |
Observação
Na implementação atual da última política de deteção de conflitos do gravador, a exclusão sempre vence quando há um conflito inserção-exclusão, exclusão-inserção ou atualização-exclusão.
Examples
Criar publicação no primeiro par (Nó1)
Neste exemplo, o script:
- Publica um banco de dados chamado
MWPubDB. - Nomeia a publicação
PublMW. - Configura a política de deteção e resolução de conflitos à medida que a última gravação vence:
, @p2p_continue_onconflict= 'true', @p2p_conflictdetection_policy = 'lastwriter'
USE [MWPubDB];
EXECUTE sp_replicationdboption
@dbname = N'MWPubDB',
@optname = N'publish',
@value = N'true';
GO
-- Adding the transactional publication
USE [MWPubDB];
EXECUTE sp_addpublication
@publication = N'PublMW',
@description = N'Peer-to-Peer publication of database ''MWPubDB'' from Publisher ''Node1''.',
@sync_method = N'native',
@retention = 0,
@allow_push = N'true',
@allow_pull = N'true',
@allow_anonymous = N'false',
@enabled_for_internet = N'false',
@snapshot_in_defaultfolder = N'true',
@compress_snapshot = N'false',
@ftp_port = 21,
@allow_subscription_copy = N'false',
@add_to_active_directory = N'false',
@repl_freq = N'continuous',
@status = N'active',
@independent_agent = N'true',
@immediate_sync = N'true',
@allow_sync_tran = N'false',
@allow_queued_tran = N'false',
@allow_dts = N'false',
@replicate_ddl = 1,
@allow_initialize_from_backup = N'true',
@enabled_for_p2p = N'true',
@enabled_for_het_sub = N'false',
@p2p_conflictdetection = N'true',
@p2p_originator_id = 100,
@p2p_continue_onconflict = 'true',
@p2p_conflictdetection_policy = 'lastwriter';
GO
USE [MWPubDB];
EXECUTE sp_addarticle
@publication = N'PublMW',
@article = N'tab1',
@source_owner = N'dbo',
@source_object = N'tab1',
@type = N'logbased',
@description = NULL,
@creation_script = NULL,
@pre_creation_cmd = N'drop',
@schema_option = 0x0000000008035DDB,
@identityrangemanagementoption = N'manual',
@destination_table = N'tab1',
@destination_owner = N'dbo',
@status = 16,
@vertical_partition = N'false',
@ins_cmd = N'CALL sp_MSins_dbotab1',
@del_cmd = N'CALL sp_MSdel_dbotab1',
@upd_cmd = N'CALL sp_MSupd_dbotab1';
GO
Criar publicação no segundo par (Nó2)
O script a seguir cria a publicação no segundo par (Nó 2).
USE [MWPubDB];
EXECUTE sp_replicationdboption
@dbname = N'MWPubDB',
@optname = N'publish',
@value = N'true';
GO
-- Adding the transactional publication
USE [MWPubDB];
EXECUTE sp_addpublication
@publication = N'PublMW',
@description = N'Peer-to-Peer publication of database ''MWPubDB'' from Publisher ''Node2''.',
@sync_method = N'native',
@retention = 0,
@allow_push = N'true',
@allow_pull = N'true',
@allow_anonymous = N'false',
@enabled_for_internet = N'false',
@snapshot_in_defaultfolder = N'true',
@compress_snapshot = N'false',
@ftp_port = 21,
@allow_subscription_copy = N'false',
@add_to_active_directory = N'false',
@repl_freq = N'continuous',
@status = N'active',
@independent_agent = N'true',
@immediate_sync = N'true',
@allow_sync_tran = N'false',
@allow_queued_tran = N'false',
@allow_dts = N'false',
@replicate_ddl = 1,
@allow_initialize_from_backup = N'true',
@enabled_for_p2p = N'true',
@enabled_for_het_sub = N'false',
@p2p_conflictdetection = N'true',
@p2p_originator_id = 1,
@p2p_continue_onconflict = 'true',
@p2p_conflictdetection_policy = 'lastwriter';
GO
USE [MWPubDB];
EXECUTE sp_addarticle
@publication = N'PublMW',
@article = N'tab1',
@source_owner = N'dbo',
@source_object = N'tab1',
@type = N'logbased',
@description = NULL,
@creation_script = NULL,
@pre_creation_cmd = N'drop',
@schema_option = 0x0000000008035DDB,
@identityrangemanagementoption = N'manual',
@destination_table = N'tab1',
@destination_owner = N'dbo',
@status = 16,
@vertical_partition = N'false',
@ins_cmd = N'CALL sp_MSins_dbotab1',
@del_cmd = N'CALL sp_MSdel_dbotab1',
@upd_cmd = N'CALL sp_MSupd_dbotab1';
GO
Criar subscrição de Node1 para Node2
USE [MWPubDB];
EXECUTE sp_addsubscription
@publication = N'PublMW',
@subscriber = N'Node2',
@destination_db = N'MWPubDB',
@subscription_type = N'Push',
@sync_type = N'replication support only',
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0;
GO
EXECUTE sp_addpushsubscription_agent
@publication = N'PublMW',
@subscriber = N'Node2',
@subscriber_db = N'MWPubDB',
@job_login = NULL,
@job_password = NULL,
@subscriber_security_mode = 1,
@frequency_type = 64,
@frequency_interval = 1,
@frequency_relative_interval = 1,
@frequency_recurrence_factor = 0,
@frequency_subday = 4,
@frequency_subday_interval = 5,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@dts_package_location = N'Distributor';
GO
Criar subscrição de Node2 para Node1
USE [MWPubDB];
EXECUTE sp_addsubscription
@publication = N'PublMW',
@subscriber = N'Node1',
@destination_db = N'MWPubDB',
@subscription_type = N'Push',
@sync_type = N'replication support only',
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0;
GO
EXECUTE sp_addpushsubscription_agent
@publication = N'PublMW',
@subscriber = N'Node1',
@subscriber_db = N'MWPubDB',
@job_login = NULL,
@job_password = NULL,
@subscriber_security_mode = 1,
@frequency_type = 64,
@frequency_interval = 1,
@frequency_relative_interval = 1,
@frequency_recurrence_factor = 0,
@frequency_subday = 4,
@frequency_subday_interval = 5,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@dts_package_location = N'Distributor';
GO