Указание способа распространения изменений для статей транзакций

Репликация транзакций позволяет указывать, как изменения данных распространяются от издателя к подписчикам. Для каждой опубликованной таблицы можно указать один из четырех способов, которыми каждая операция (INSERT, UPDATE или DELETE) будет передаваться подписчику:

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

  • Укажите, что изменение следует распространять с помощью оператора INSERT, UPDATE или DELETE (по умолчанию для подписчиков, не использующих SQL Server).

  • Укажите, что должна использоваться пользовательская хранимая процедура.

  • Укажите, что данное действие не должно выполняться на любом подписчике. Транзакции этого типа не реплицируются.

По умолчанию, репликация транзакций распространяет изменения на подписчики при помощи набора хранимых процедур, установленных на каждом подписчике. Операции вставки, обновления или удаления в таблице издателя преобразовываются в вызовы хранимой процедуры на подписчике. Хранимая процедура принимает параметры, которые соответствуют столбцам в таблице, допуская изменение этих столбцов в подписчике.

Чтобы настроить метод распространения изменений данных в статьях транзакций, см. раздел Задание метода распространения изменений данных в транзакционные статьи.

Стандартные и пользовательские хранимые процедуры

Три процедуры, создаваемые репликацией по умолчанию для каждой статьи таблицы:

  • sp_MSins_<имя_таблицы>, обрабатывающая операции вставки.

  • sp_MSupd_<имя_таблицы>, обрабатывающая операции обновления.

  • sp_MSdel_<имя_таблицы>, обрабатывающая операции удаления.

Используемое в процедуре <имя_таблицы> зависит от того, как статья была добавлена в публикацию и содержит ли база данных подписки таблицу другого владельца с таким же именем.

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

Если указываются стандартные или пользовательские процедуры репликации, указывается также синтаксис вызова для каждой процедуры (при использовании процедур по умолчанию репликация выбирает умолчания). Синтаксис вызова определяет структуру параметров, предоставляемых процедуре, а также количество сведений, посылаемых подписчику с каждым изменением данных. Дополнительные сведения см. в подразделе «Синтаксис вызова для хранимых процедур» этого раздела.

Аспекты использования пользовательских хранимых процедур

При использовании пользовательских хранимых процедур примите во внимание следующие соображения:

  • Логику необходимо поддерживать в хранимой процедуре; Корпорация Майкрософт не предоставляет поддержку пользовательской логики.

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

  • Схема в подписчике, как правило, идентична схеме в издателе, однако при использовании фильтрации столбцов схема в подписчике может быть подмножеством схемы издателя. Однако если необходимо преобразовать схему по мере перемещения данных таким образом, чтобы схема на подписчике не являлась подмножеством схемы на издателе, рекомендуется использовать SQL Server 2014 Integration Services (SSIS). Дополнительные сведения см. в разделе Службы SQL Server Integration Services.

  • При внесении изменений схемы в опубликованную таблицу пользовательские процедуры должны быть созданы заново. Дополнительные сведения см. в статье Повторное создание пользовательских процедур транзакций с учетом изменений в схеме.

  • При использовании значений больше 1 для параметра -SubscriptionStreams агента распространителя убедитесь, что обновления первичных ключевых столбцов выполнены успешно. Например:

    update ... set pk = 2 where pk = 1 -- update 1  
    update ... set pk = 3 where pk = 2 -- update 2  
    

    Если агент распространителя использует больше одного соединения, то эти два обновления могут реплицироваться через другие соединения. Если обновление 1 применяется первым, то проблем не существует; если первым применяется обновление 2, возвращается сообщение «0 строк затронуто», т. к. обновление 1 еще не произошло. Данная ситуация в процедурах по умолчанию вызывает ошибку, если не существует строк, затронутых при обновлении:

    if @@rowcount = 0  
        if @@microsoftversion>0x07320000  
            exec sys.sp_MSreplraiserror 20598  
    

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

Синтаксис вызова для хранимых процедур

Существует пять вариантов синтаксиса, который применяется для вызова процедур, используемых репликацией транзакций:

  • Синтаксис функции CALL. Может использоваться для вставок, обновлений и удалений. По умолчанию репликация использует этот синтаксис для вставок и удалений.

  • Синтаксис функции SCALL. Может применяться только для обновлений. По умолчанию репликация использует этот синтаксис для обновлений.

  • Синтаксис функции MCALL. Может применяться только для обновлений.

  • Синтаксис функции XCALL. Может использоваться для обновлений и удалений.

  • VCALL. Применяется для обновляемых подписок. Только для внутреннего применения.

Каждый метод отличается по количеству данных, распространяемых на подписчик. Например, SCALL передается в значениях только для столбцов, реально затронутых обновлением. Напротив, XCALL запрашивает все столбцы (независимо от того, затронуты ли они обновлением) и все старые значения данных каждого столбца. Во многих случаях синтаксис SCALL целесообразен для обновлений, но если приложению нужны все значения данных во время обновления, это позволяет указать синтаксис XCALL.

Синтаксис функции CALL

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

c1, c2, c3,... cn  

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

c1, c2, c3,... cn, pkc1, pkc2, pkc3,... pkcn  

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

pkc1, pkc2, pkc3,... pkcn  

Синтаксис функции SCALL

UPDATE Хранимые процедуры
Инструкции обработки UPDATE хранимых процедур передаются только для тех столбцов, которые изменились, а затем исходные значения для столбцов первичного ключа, а затем параметр битовой маски (binary(n)) с измененными столбцами. В следующем примере столбец 2 (c2) не был изменен:

c1, , c3,... cn, pkc1, pkc2, pkc3,... pkcn, bitmask  

Синтаксис функции MCALL

UPDATE Хранимые процедуры
Инструкции обработки UPDATE хранимых процедур будут переданы обновленные значения для всех столбцов, определенных в статье, а затем исходные значения для столбцов первичного ключа, а затем параметр битовой маски (binary(n)) с измененными столбцами:

c1, c2, c3,... cn, pkc1, pkc2, pkc3,... pkcn, bitmask  

Синтаксис функции XCALL.

UPDATE Хранимые процедуры
Хранимым процедурам, обрабатывающим инструкции UPDATE, будут переданы исходные значения (значения до изменения) для всех столбцов, определённых в публикации, а затем обновлённые значения (значения после изменения) для всех столбцов, определённых в публикации:

old-c1, old-c2, old-c3,... old-cn, c1, c2, c3,... cn,  

DELETE Хранимые процедуры
Хранимым процедурам, обрабатывающим инструкции DELETE, будут переданы исходные значения (значения до изменения) для всех столбцов, определенных в публикации:

old-c1, old-c2, old-c3,... old-cn  

Примечание.

При использовании функции XCALL предполагается, что значения двоичного образа до обработки для столбцов text и image равны NULL.

Примеры

Ниже приведены процедуры по умолчанию, созданные для Vendor Table примера базы данных Adventure Works.

--INSERT procedure using CALL syntax  
create procedure [sp_MSins_PurchasingVendor]   
  @c1 int,@c2 nvarchar(15),@c3 nvarchar(50),@c4 tinyint,@c5 bit,@c6 bit,@c7 nvarchar(1024),@c8 datetime  
as   
begin   
insert into [Purchasing].[Vendor]([VendorID]  
,[AccountNumber]  
,[Name]  
,[CreditRating]  
,[PreferredVendorStatus]  
,[ActiveFlag]  
,[PurchasingWebServiceURL]  
,[ModifiedDate])  
values (   
 @c1  
,@c2  
,@c3  
,@c4  
,@c5  
,@c6  
,@c7  
,@c8  
 )   
end  
go  
  
--UPDATE procedure using SCALL syntax  
create procedure [sp_MSupd_PurchasingVendor]   
 @c1 int = null,@c2 nvarchar(15) = null,@c3 nvarchar(50) = null,@c4 tinyint = null,@c5 bit = null,@c6 bit = null,@c7 nvarchar(1024) = null,@c8 datetime = null,@pkc1 int  
,@bitmap binary(2)  
as  
begin  
update [Purchasing].[Vendor] set   
 [AccountNumber] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [AccountNumber] end  
,[Name] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [Name] end  
,[CreditRating] = case substring(@bitmap,1,1) & 8 when 8 then @c4 else [CreditRating] end  
,[PreferredVendorStatus] = case substring(@bitmap,1,1) & 16 when 16 then @c5 else [PreferredVendorStatus] end  
,[ActiveFlag] = case substring(@bitmap,1,1) & 32 when 32 then @c6 else [ActiveFlag] end  
,[PurchasingWebServiceURL] = case substring(@bitmap,1,1) & 64 when 64 then @c7 else [PurchasingWebServiceURL] end  
,[ModifiedDate] = case substring(@bitmap,1,1) & 128 when 128 then @c8 else [ModifiedDate] end  
where [VendorID] = @pkc1  
if @@rowcount = 0  
    if @@microsoftversion>0x07320000  
        exec sp_MSreplraiserror 20598  
end  
go  
  
--DELETE procedure using CALL syntax  
create procedure [sp_MSdel_PurchasingVendor]   
  @pkc1 int  
as   
begin   
delete [Purchasing].[Vendor]  
where [VendorID] = @pkc1  
if @@rowcount = 0  
    if @@microsoftversion>0x07320000  
        exec sp_MSreplraiserror 20598  
end   
go  

См. также

Настройки статьи для транзакционной репликации