Sql-Server

Merge Replication 自定義同步週期及其性能

  • August 7, 2017

我試圖在兩台伺服器之間實現合併複製,一個發布者和一個訂閱者。

假設這些表:

--Main table in Publisher
Ticket (id, userId, reqId, blockedDate, usedDate, returnDate, transferDate, ...)

--On Subscriber (The fields are in Publication)
Ticket (id, userId, blockedDate, usedDate)

我們必須將目前日期分配給任何transferDate時候到訂閱者的行,並分配給returnDate它從訂閱者返回的任何時候。由於我們必須考慮文件同步(使用 USB 記憶棒向/從訂閱者傳輸/返回數據!),因此必須在同步文件同步或複制時分配這些欄位。

我知道您可以為衝突解決添加自定義業務邏輯(發生衝突時)。我正在尋找諸如複製事件觸發器之類的東西,這使我能夠從 Publication 中操作某些欄位(甚至在需要時可以操作另一個表)。

問題

  • 是否可以手動處理複製事件(推送和拉取)?(自定義或覆蓋 PULL/PUSH。不是衝突解決程序)
  • 你能給我一個在distributed transactionSP 的幫助下實現自定義合併複製和同步之間的比較嗎?

我需要安排同步(在數據庫伺服器上沒有負載的午夜),但是我們非常需要我們能夠手動同步(從我們的 Web 應用程序中)。

在第二個問題中,我需要它們的性能、可靠性,當然還有它們的可維護性。這些因素,尤其是前兩個因素,是一個大問題。假設 Publisher 可能有大約幾百萬條記錄,Subscriber 可能有大約幾萬條記錄。因此,每次同步都會傳輸大約一萬條記錄。

合併複製檢查行;如果有變化並且沒有衝突,則行合併。如果存在衝突,衝突解決程序(可能是您的自定義儲存過程解決程序)會處理衝突。我想在第一種情況下(數據更改而沒有衝突)編寫自己的邏輯,而不是 SQL 的內置合併機制。顯然我想定制它。

文章中只有id, userId, blockedDate, usedDate專欄。我想returnDate在 aTicket返回到 Publisher 時填寫(在pull上)並transferDate在 aTicket到 Subscriber 時填寫(在push上)。

要自定義合併過程,您需要實現自定義業務邏輯處理程序(需要 .NET 程式碼 - 無法使用 TSQL 實現)。請參閱文件中的在合併同步期間執行業務邏輯。它在 SQL Server 2012 及更高版本中可用。

重寫方法 Update、Insert 和 Commit 以轉換更改的行,以及沖突解決器方法以修改衝突邏輯。不能使用 T-SQL,必須使用 .NET 程式碼。主要限制是每行呼叫一次每個可覆蓋的方法(如 SSIS 行轉換),據我所知,沒有對所有更改的行呼叫方法。

有一些解決方法可以處理您的情況,但這是通用解決方案。

這是 BOL C# 模板:

using System;
using System.Text;
using System.Data;
using System.Data.Common;
using Microsoft.SqlServer.Replication.BusinessLogicSupport;
using Microsoft.Samples.SqlServer.BusinessLogicHandler;

namespace Microsoft.Samples.SqlServer.BusinessLogicHandler
{
public class OrderEntryBusinessLogicHandler :
 Microsoft.SqlServer.Replication.BusinessLogicSupport.BusinessLogicModule
{
   // Variables to hold server names.
   private string publisherName;
   private string subscriberName;

   public OrderEntryBusinessLogicHandler()
   {
   }

   // Implement the Initialize method to get publication 
   // and subscription information.
   public override void Initialize(
       string publisher,
       string subscriber,
       string distributor,
       string publisherDB,
       string subscriberDB,
       string articleName)
   {
       // Set the Publisher and Subscriber names.
       publisherName = publisher;
       subscriberName = subscriber;
   }

   // Declare what types of row changes, conflicts, or errors to handle.
   override public ChangeStates HandledChangeStates
   {
       get
       {
           // Handle Subscriber inserts, updates and deletes.
           return ChangeStates.SubscriberInserts |
             ChangeStates.SubscriberUpdates | ChangeStates.SubscriberDeletes;
       }
   }

   public override ActionOnDataChange InsertHandler(SourceIdentifier insertSource,
     DataSet insertedDataSet, ref DataSet customDataSet, ref int historyLogLevel,
     ref string historyLogMessage)
   {
       // custom logic for updates                 
   }

   public override ActionOnDataChange UpdateHandler(SourceIdentifier updateSource,
     DataSet updatedDataSet, ref DataSet customDataSet, ref int historyLogLevel,
     ref string historyLogMessage)
   {
// custom logic for updates 
 }
   public override ActionOnDataDelete DeleteHandler(SourceIdentifier deleteSource,
     DataSet deletedDataSet, ref int historyLogLevel, ref string historyLogMessage)
   {
    // custom logic for deletes 
}
}

引用自:https://dba.stackexchange.com/questions/182207