Udostępnij za pośrednictwem


Artykuły transakcyjne — określ, jak zmiany są propagowane

Dotyczy:programu SQL ServerAzure SQL Managed Instance

Replikacja transakcyjna umożliwia określenie, w jaki sposób zmiany danych są propagowane z wydawcy do subskrybentów. Dla każdej opublikowanej tabeli można określić jeden z czterech sposobów propagacji każdej operacji (INSERT, UPDATE lub DELETE) do subskrybenta:

  • Określ, że replikacja transakcyjna powinna spowodować utworzenie skryptu, a następnie wywołanie procedury składowanej w celu propagowania zmian do subskrybentów (ustawienie domyślne).

  • Określ, że zmiana powinna być propagowana przy użyciu instrukcji INSERT, UPDATE lub DELETE (wartość domyślna dla subskrybentów innych niż subskrybenci programu SQL Server).

  • Określ, że należy użyć niestandardowej procedury przechowywanej.

  • Określ, że ta akcja nie powinna być wykonywana w żadnym subskrybencie. Transakcje tego typu nie są replikowane.

Domyślnie replikacja transakcyjna propaguje zmiany do subskrybentów za pomocą zestawu procedur składowanych zainstalowanych na każdym subskrybencie. W przypadku wystąpienia wstawiania, aktualizowania lub usuwania w tabeli u Wydawcy, operacja jest tłumaczona na wywołanie procedury składowanej u Subskrybenta. Procedura składowana akceptuje parametry, które są mapowane na kolumny w tabeli, co pozwala na zmianę tych kolumn u subskrybenta.

Aby ustawić metodę propagacji zmian danych w artykułach transakcyjnych, zobacz Set the Propagation Method for Data Changes to Transactional Articles.

Domyślne i niestandardowe procedury składowane

Trzy procedury replikacji tworzone domyślnie dla każdego artykułu tabeli to:

  • sp_MSins_<nazwa_tabeli>, która obsługuje wstawki.

  • sp_MSupd_<nazwa_tabeli>, która obsługuje aktualizacje.

  • sp_MSdel_<nazwa_tabeli>, która obsługuje usuwanie.

< nazwa_tabeli> używana w procedurze zależy od tego, jak artykuł został dodany do publikacji i czy baza danych subskrypcji zawiera tabelę o tej samej nazwie z innym właścicielem.

Każdą z tych procedur można zastąpić niestandardową procedurą określoną podczas dodawania artykułu do publikacji. Niestandardowe procedury są używane, jeśli aplikacja wymaga logiki niestandardowej, takiej jak wstawianie danych do tabeli audytu, gdy wiersz jest aktualizowany u subskrybenta. Aby uzyskać więcej informacji na temat definiowania własnych procedur składowanych, zobacz tematy wymienione powyżej.

Jeśli określisz domyślne procedury replikacji lub niestandardowe procedury, należy również określić składnię wywołania dla każdej procedury (replikacja wybiera wartości domyślne, jeśli używasz procedur domyślnych). Składnia wywołania określa strukturę parametrów podanych w procedurze i ilość informacji wysyłanych do subskrybenta z każdą zmianą danych. Aby uzyskać więcej informacji, zobacz sekcję "Składnia wywoływania procedur składowanych" w tym temacie.

Zagadnienia dotyczące używania niestandardowych procedur składowanych

Podczas korzystania z niestandardowych procedur składowanych należy wziąć pod uwagę następujące kwestie:

  • Musisz obsługiwać logikę w procedurze składowanej; Microsoft nie zapewnia wsparcia dla logiki niestandardowej.

  • Aby uniknąć konfliktów z transakcjami używanymi przez replikację, jawne transakcje nie powinny być używane w niestandardowych procedurach.

  • Schemat u subskrybenta jest zwykle identyczny ze schematem u wydawcy, ale może być również podzbiorem schematu wydawcy, jeśli stosuje się filtrowanie kolumn. Jeśli jednak musisz przekształcić schemat w miarę przenoszenia danych, tak aby schemat na subskrybentu nie był podzbiorem schematu w programie Publisher, zalecanym rozwiązaniem jest program SQL Server 2019 Integration Services (SSIS). Aby uzyskać więcej informacji, zobacz SQL Server Integration Services.

  • Jeśli wprowadzisz zmiany schematu w opublikowanej tabeli, procedury niestandardowe muszą zostać ponownie wygenerowane. Aby uzyskać więcej informacji, zobacz Ponowne generowanie niestandardowych procedur transakcyjnych w celu odzwierciedlenia zmian schematu.

  • Jeśli używasz wartości większej niż 1 dla parametru -SubscriptionStreams agenta dystrybucji, musisz upewnić się, że aktualizacje kolumn klucza podstawowego zakończyły się pomyślnie. Na przykład:

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

    Jeśli agent dystrybucji używa więcej niż jednego połączenia, te dwie aktualizacje mogą być replikowane za pośrednictwem różnych połączeń. Jeśli najpierw zastosowano aktualizację 1, nie ma problemu; Jeśli najpierw zastosowano aktualizację 2, zostanie zwrócona wartość "0 wierszy, których dotyczy problem", ponieważ aktualizacja 1 jeszcze nie wystąpiła. Ta sytuacja jest obsługiwana w domyślnych procedurach przez zgłoszenie błędu, jeśli w przypadku aktualizacji nie są zmienione żadne wiersze.

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

    Wygenerowanie błędu wymusza na agencie dystrybucji ponawianie prób aktualizacji za pośrednictwem pojedynczego połączenia, co zakończy się powodzeniem. Niestandardowe procedury składowane muszą zawierać podobną logikę.

Wywoływanie składni procedur składowanych

Istnieje pięć opcji składni używanych do wywoływania procedur używanych przez replikację transakcyjną:

  • Składnia WYWOŁANIA. Może służyć do wstawiania, aktualizacji i usuwania. Domyślnie replikacja używa tej składni do wstawiania i usuwania.

  • Składnia SCALL. Można go używać tylko w przypadku aktualizacji. Domyślnie replikacja używa tej składni do aktualizacji.

  • Składnia MCALL. Można go używać tylko w przypadku aktualizacji.

  • Składnia XCALL. Może służyć do aktualizacji i usuwania.

  • VCALL. Służy do aktualizowania subskrypcji. Tylko do użytku wewnętrznego.

Każda metoda różni się ilością danych propagowanych do subskrybenta. Na przykład funkcja SCALL przekazuje wartości tylko dla kolumn, na które faktycznie ma wpływ aktualizacja. Natomiast funkcja XCALL wymaga wszystkich kolumn (niezależnie od tego, czy ma to wpływ na aktualizację, czy nie) oraz wszystkich starych wartości danych dla każdej kolumny. W wielu przypadkach funkcja SCALL jest odpowiednia dla aktualizacji, ale jeśli aplikacja wymaga wszystkich wartości danych podczas aktualizacji, program XCALL na to zezwala.

Składnia WYWOŁANIA

Procedury składowane typu INSERT
Procedury składowane obsługujące instrukcje INSERT otrzymają wstawione wartości dla wszystkich kolumn.

c1, c2, c3,... cn  

AKTUALIZOWANIE procedur składowanych
Procedury składowane, które obsługują instrukcje UPDATE, będą otrzymywać aktualne wartości dla wszystkich kolumn zdefiniowanych w artykule, a następnie oryginalne wartości kolumn klucza podstawowego (nie określa się, które kolumny zostały zmienione).

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

Usuń procedury składowane
Procedury składowane obsługujące instrukcje DELETE będą przekazywane wartości dla kolumn klucza podstawowego:

pkc1, pkc2, pkc3,... pkcn  

Składnia SCALL

AKTUALIZUJ procedury składowane
Procedury składowane obsługujące instrukcje UPDATE otrzymają tylko zaktualizowane wartości dla tych kolumn, które uległy zmianie, oraz oryginalne wartości dla kolumn klucza podstawowego, a także parametr maski bitów (binary(n)), który wskazuje zmienione kolumny. W poniższym przykładzie kolumna 2 (c2) nie zmieniła się:

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

Składnia MCALL

Aktualizuj procedury składowane
Procedury składowane obsługujące instrukcje UPDATE otrzymają zaktualizowane wartości dla wszystkich kolumn zdefiniowanych w instrukcji, następnie oryginalne wartości kolumn klucza podstawowego, a następnie parametr maski bitowej (binary(n)), który wskazuje zmienione kolumny.

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

Składnia XCALL

Aktualizacja procedur składowanych
Procedurom składowanym obsługującym instrukcje UPDATE zostaną przekazane oryginalne wartości (stan przed zmianą) dla wszystkich kolumn zdefiniowanych w definicji artykułu, a następnie zaktualizowane wartości (stan po zmianie) dla wszystkich kolumn zdefiniowanych w definicji artykułu.

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

USUŃ procedury składowane
Procedury składowane obsługujące instrukcje DELETE zostaną przekazane oryginalne (przed obrazem) wartości dla wszystkich kolumn zdefiniowanych w artykule:

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

Notatka

W przypadku korzystania z XCALL wartości przed obrazem dla tekstu i kolumn obrazu powinny mieć wartość NULL.

Przykłady

Poniższe procedury to domyślne procedury utworzone dla Vendor Table w przykładowej bazie danych firmy 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