트랜잭션 아티클 - 변경 내용을 전파하는 방법 지정

적용 대상:SQL ServerAzure SQL Managed Instance

트랜잭션 복제를 사용하면 데이터 변경 내용이 게시자에서 구독자에게 전파되는 방법을 지정할 수 있습니다. 다음 4가지 중 하나를 사용하여 게시된 각 테이블에 대해 INSERT, UPDATE 또는 DELETE 등의 각 작업이 구독자로 전파되는 방법을 지정할 수 있습니다.

  • 트랜잭션 복제가 저장 프로시저를 스크립팅한 후 저장 프로시저를 호출하여 변경 내용을 구독자로 전파하도록 지정합니다(기본값).

  • INSERT, UPDATE 또는 DELETE 문(SQL Server 이외 구독자의 기본값)을 사용하여 변경 내용이 전파되도록 지정합니다.

  • 사용자 지정 저장 프로시저를 사용해야 되도록 지정합니다.

  • 구독자에서 이 작업을 수행하지 않도록 지정합니다. 해당 형식의 트랜잭션은 복제되지 않습니다.

기본적으로 트랜잭션 복제는 각 구독자에 설치된 저장 프로시저 집합을 통해 변경 내용을 구독자에게 전파합니다. 게시자의 테이블에서 삽입, 업데이트 또는 삭제 작업이 발생하면 이러한 작업은 구독자에서 저장 프로시저에 대한 호출로 변환됩니다. 저장 프로시저는 테이블의 열에 매핑되는 매개 변수를 허용하므로 구독자에서 해당 열을 변경할 수 있습니다.

트랜잭션 아티클에 대한 데이터 변경에 대한 전파 방법을 설정하려면 트랜잭션 아티클에 대한 데이터 변경 내용에 대한 전파 방법 설정을 참조 하세요.

기본 저장 프로시저 및 사용자 지정 저장 프로시저

복제 시 각 테이블 아티클에 대해 기본적으로 생성되는 3가지 프로시저는 다음과 같습니다.

  • <삽입을 처리하는 sp_MSins_tablename>입니다.

  • <업데이트를 처리하는 sp_MSupd_tablename>입니다.

  • <삭제를 처리하는 sp_MSdel_tablename>입니다.

프로시저에서 사용하는 <tablename> 은 아티클을 게시에 추가하는 방법과 구독 데이터베이스에 소유자는 다르지만 이름이 같은 테이블이 포함되어 있는지 여부에 따라 다릅니다.

이러한 프로시저는 아티클을 게시에 추가할 때 지정하는 사용자 지정 프로시저로 바꿀 수 있습니다. 구독자에서 행이 업데이트될 때 애플리케이션에 감사 테이블에 데이터를 삽입하는 것과 같은 사용자 지정 논리가 필요한 경우 사용자 지정 프로시저가 사용됩니다. 사용자 지정 저장 프로시저를 지정하는 방법에 대한 자세한 내용은 위에 나열된 항목을 참조하세요.

기본 복제 프로시저 또는 사용자 지정 프로시저를 지정하는 경우 각 프로시저에 대한 호출 구문도 지정합니다(기본 프로시저를 사용하는 경우 복제는 기본값을 선택함). 호출 구문은 프로시저에 제공된 매개 변수의 구조와 각 데이터가 변경될 때마다 구독자에게 전송되는 정보의 양을 결정합니다. 자세한 내용은 이 항목의 "저장 프로시저에 대한 호출 구문" 섹션을 참조하세요.

사용자 지정 저장 프로시저 사용에 대한 고려 사항

사용자 지정 저장 프로시저를 사용할 때는 다음 사항을 고려해야 합니다.

  • 저장 프로시저에서 논리를 지원해야 합니다. Microsoft는 사용자 지정 논리에 대한 지원을 제공하지 않습니다.

  • 복제에서 사용하는 트랜잭션과 충돌을 피하려면 사용자 지정 프로시저에서 명시적 트랜잭션을 사용하지 않아야 합니다.

  • 구독자의 스키마는 일반적으로 게시자의 스키마와 동일하지만 열 필터링을 사용하는 경우 게시자 스키마의 하위 집합일 수도 있습니다. 그러나 구독자의 스키마가 게시자의 스키마 하위 집합이 아니도록 데이터가 이동될 때 스키마를 변환해야 하는 경우 SQL Server 2019 Integration Services(SSIS)가 권장되는 솔루션입니다. 자세한 내용은 SQL Server Integration Services를 참조하세요.

  • 게시된 테이블에 대해 스키마 변경을 적용하면 사용자 지정 프로시저를 다시 생성해야 합니다. 자세한 내용은 스키마 변경 내용을 반영하기 위해 사용자 지정 트랜잭션 프로시저 다시 생성을 참조하세요.

  • 배포 에이전트의 -SubscriptionStreams 매개 변수에 대해 1보다 큰 값을 사용하는 경우 기본 키 열에 대한 업데이트가 성공했는지 확인해야 합니다. 예:

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

    배포 에이전트가 둘 이상의 연결을 사용하는 경우 이러한 두 업데이트는 서로 다른 연결을 통해 복제될 수 있습니다. 업데이트 1이 먼저 적용되는 경우 문제가 없습니다. 업데이트 2가 먼저 적용되면 업데이트 1이 아직 발생하지 않았기 때문에 '영향을 받는 행 0개'가 반환됩니다. 기본 프로시저에서는 업데이트 시 변경된 행이 없을 경우 오류를 발생시켜 이 상황을 처리합니다.

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

    오류가 발생하면 배포 에이전트가 단일 연결을 통해 업데이트를 다시 시도하고 이로 인해 업데이트가 성공적으로 수행됩니다. 사용자 지정 저장 프로시저에는 유사한 논리가 포함되어야 합니다.

저장 프로시저 호출 구문

트랜잭션 복제에서 사용되는 프로시저를 호출하는 데 사용되는 구문에는 5가지 옵션이 있습니다.

  • 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을 사용하는 경우 텍스트이미지 열의 이전 이미지 값은 NULL이어야 합니다.

다음 절차는 Adventure Works 샘플 데이터베이스에서 Vendor Table 만든 기본 프로시저입니다.

--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  

참고 항목

트랜잭션 복제에 대한 문서 옵션