Инструкции UPDATE могут реплицироваться как пары DELETE/INSERT

В этой статье описывается, что инструкции Update могут реплицироваться как пары DELETE/INSERT.

Оригинальная версия продукта: SQL Server
Исходный номер базы знаний: 238254

Сводка

Если какой-либо столбец, являющийся частью уникального ограничения, обновляется, то SQL Server реализует обновление как "отложенное обновление", то есть как пара операцийDELETE/INSERT. Это "отложенное обновление" приводит к тому, что репликация отправляет подписчикам DELETE/INSERT пару операторов. Существуют и другие ситуации, которые могут привести к отложению обновления. Поэтому любая бизнес-логика, реализованная в UPDATE триггерах или пользовательских хранимых процедурах на подписчике, также должна быть включена DELETE/INSERT в триггеры или пользовательские хранимые процедуры.

Дополнительная информация

Поведение по умолчанию в репликации транзакций заключается в использовании INSERTпользовательских UPDATE хранимых процедур и DELETE для применения изменений в подписчиках.

INSERT операторы, сделанные на издателе, применяются к подписчикам через вызов хранимой INSERT процедуры. Аналогичным образом оператор DELETE применяется через вызов хранимой DELETE процедуры.

Однако когда UPDATE инструкция выполняется как "отложенное обновление", агент logreader помещает пару вызовов DELETE/INSERT хранимых процедур в базе данных распространителя для применения к подписчикам, а не вызов хранимой процедуры обновления. Например, предположим, что у вас есть таблица публикации с именем TABLE1с тремя столбцами:

  • col1 int
  • col2 int
  • col3 varchar(30)

Единственное уникальное ограничение для TABLE1 определяется col1 с помощью ограничения первичного ключа. Предположим, что у вас есть одна запись (1,1, "Даллас").

При выполнении этого кода:

UPDATE TABLE1 set col1 = 3 where col3 = 'Dallas'

Оператор UPDATE реализуется SQL Server как пара операторовINSERTDELETE/, так как выполняется обновление col1, для которого определен уникальный индекс. Таким образом, средство чтения журнала помещает пару вызовов DELETE/INSERT в базу данных распространителя. Это может повлиять на любую бизнес-логику, которая присутствует в триггерах или пользовательских хранимых процедурах на подписчике. Для обработки этой ситуации следует включить дополнительную бизнес-логику в DELETEINSERT и триггеры или хранимые процедуры.

Если вы предпочитаете использовать одну логику и хотите, чтобы все UPDATE команды реплицировались как DELETE/INSERT пары, можно включить флаг трассировки.

Кроме того, если в публикации используется горизонтальный фильтр, а обновленная строка не соответствует условию фильтра, подписчикам отправляется только DELETE вызов процедуры. Если обновленная строка ранее не соответствовала условию фильтра, но соответствует условию после обновления, то в процессе репликации отправляется только INSERT вызов процедуры.

В предыдущем примере предположим, что у вас также есть горизонтальный фильтр, определенный для TABLE1: where col3 = 'Dallas'. При выполнении этого кода:

UPDATE table1 set col3 = 'New York' where col1 = 3

Агент logreader размещает только вызов хранимой DELETE процедуры для применения к подписчикам, так как обновленная строка не соответствует критериям горизонтального фильтра.

Теперь при выполнении этого кода:

UPDATE table1 set col3 = 'Dallas' where col1 = 3

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

Хотя операция UPDATE была выполнена на издателе, на подписчике применяются только соответствующие команды.