Ограничение уникального ключа репликации слиянием

У меня есть настройка репликации слиянием SQL Server на двух серверах, и я получаю сообщение об ошибке ограничения ключа при выполнении синхронизации. Единственный способ решить эту проблему - удалить запись на одном из серверов, а затем запустить синхронизацию.

Вопрос: Есть ли способ настроить репликацию или распознаватель так, чтобы запись издателя побеждала, а запись подписчика автоматически удалялась при обнаружении нарушения уникального или первичного ключа?

Образец таблицы:

CREATE TABLE [dbo].[tblPeople](
  [ID] [bigint] IDENTITY(1,1) NOT NULL,
  [col1] [int] NULL,
  [col2] [int] NULL,
  [col3] [int] NULL,
  [name] [varchar](52) NULL 
CONSTRAINT [UK_keys] UNIQUE NONCLUSTERED 
(
  [col1] ASC,
  [col2] ASC,
  [col3] ASC
)

Вставить на сервере 1

INSERT into tblPeople (col1, col2, col3, name) values (1, 1, 1, 'Server 1 Insert')

Вставить на сервере 2

INSERT into tblPeople (col1, col2, col3, name) values (1, 1, 1, 'Server 2 Insert')

Синхронизация триггера, которая приводит к этой ошибке конфликта, и оба сервера имеют свою собственную версию этой записи.

Вставка строки в "SERVER1.TestDb" не может быть передана в "SERVER2.TestDb". Эта ошибка может быть вызвана нарушением ограничения. Нарушение ограничения UNIQUE KEY 'UK_keys'. Невозможно вставить дубликат ключа в объект 'dbo.tblPeople'. Дубликат значения ключа (1, 1, 1).

Все, что я прочитал об этом, предполагает добавление уникального guid или использование столбцов идентификаторов, что не является решением этой проблемы. Диапазоны идентификаторов работают отлично, и я даже могу создать свой собственный rowguid, но это все еще не решает нарушение ограничения, когда мне приходится вручную удалять записи.

Этот человек задал похожий вопрос, но мне нужен уникальный ключ поверх руководства и удостоверения личности. Автоматически разрешать конфликт слияния первичного ключа

1 ответ

Решение

Эта проблема была решена путем установки значения компенсатора_for_errors в статье слияния. По умолчанию SQL Server не запускает распознаватель при возникновении ошибки ограничения. Вы не можете изменить этот параметр через пользовательский интерфейс и должны использовать t-sql для его обновления.

exec sp_changemergearticle @publication = 'PublicationName' 
, @article = 'TableName'
, @property = 'compensate_for_errors'
, @value = N'true'
, @force_invalidate_snapshot = true 
, @force_reinit_subscription = true

https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.replication.mergearticle.compensateforerrors.aspx

Другие вопросы по тегам