發行者端與訂閱者端的資料不符

在下列情況下,「發行者」與「訂閱者」端的資料視為無非聚合性 (亦即資料不符):

  • 「訂閱者」端與「發行者」端的資料列數目不同,而且發行集未經篩選。如果發行集經過篩選,資料列的數目也可能會不同。

  • 「發行者」端與「訂閱者」端之一個或多個資料列的資料在內容上不同。

說明

「發行者」端與「訂閱者」端的資料由於下列原因而無法聚合:

  • 在「訂閱者」端應視為唯讀之資料被更新。訂閱資料庫應視為唯讀,除非您在使用合併式複寫、具有可更新訂閱的交易式複寫或點對點交易式複寫。

  • 觸發程序用於訂閱者端。「訂閱者」端的觸發程序可以修改資料,而且如果觸發程序發出 ROLLBACK 陳述式,還可以防止資料被更新。

  • 指令碼由訂閱者而非發行者的複寫執行。

  • 交易式發行集的複寫預存程序執行,於訂閱者端產生不同的結果。

  • 條件約束違規或其他問題,使資料列無法在訂閱者端插入、更新或刪除。

使用者動作

下列動作描述如何判定資料為非聚合性,以及如何將其聚合:

  1. 使用驗證或 tablediff 公用程式判定資料是否為非聚合性:

    • 若可以執行散發代理程式或合併代理程式,請執行二進位總和檢查碼驗證,以決定是否遺漏資料。您亦可使用資料列計數驗證,但這種方法無法顯現資料內容的差異。如需詳細資訊,請參閱<驗證複寫的資料>。

    • 如果「散發代理程式」或「合併代理程式」無法執行,則透過執行 tablediff 公用程式來判斷資料是否為非聚合性。如需有關在複寫資料表上使用此公用程式的資訊,請參閱<如何:比較複寫資料表的差異 (複寫程式設計)>。

  2. 如果資料為非聚合性,則可以使用 tablediff 公用程式來產生 Transact-SQL 指令碼將資料聚合。如需詳細資訊,請參閱<tablediff 公用程式>。

查找非聚合的原因

下列動作可處理「解釋」一節列出的原因:

  • 資料在複寫以外的「訂閱者」端中更新:

    • 如果您要允許使用者在「訂閱者」端插入、更新並刪除資料,則使用合併式複寫、具有可更新訂閱的交易式複寫或點對點交易式複寫。如需詳細資訊,請參閱<合併式複寫概觀>和<交易式複寫的發行集類型>。

    • 如果您要防止使用者在「訂閱者」端插入、更新及刪除資料,請為每個包含 ROLLBACK 字並使用 NOT FOR REPLICATION 選項的資料表建立觸發程序 (防止在複寫代理程式執行作業時引發觸發程序)。例如:

      USE AdventureWorks2008R2;
      GO
      CREATE TRIGGER prevent_user_dml
      ON Person.Address
      FOR INSERT, UPDATE, DELETE
      NOT FOR REPLICATION
      AS
      ROLLBACK;
      

      如需詳細資訊,請參閱<CREATE TRIGGER (Transact-SQL)>和<使用 NOT FOR REPLICATION 控制條件約束、識別和觸發程序>。

  • 觸發程序用於訂閱者端。必須適當管理訂閱者的觸發程序,以免造成無法聚合或其他問題:

    • 若您使用合併式複寫、可更新訂閱交易式複寫或點對點交易式複寫,觸發程序應只在訂閱者端造成資料變更。如需詳細資訊,請參閱<合併式複寫概觀>和<交易式複寫的發行集類型>。

    • 在多數情況下,觸發程序應使用 NOT FOR REPLICATION 選項。考慮將資料插入追蹤資料表的觸發程序:在使用者原始插入資料列時,觸發程序可以引發並可於追蹤資料表輸入資料列;但是資料複寫至訂閱者時,觸發程序不可引發,因為會導致不必要的資料列插入追蹤資料表內。

      若觸發程序包含 ROLLBACK 陳述式,且觸發程序未使用 NOT FOR REPLICATION 選項,則可能無法套用複寫到訂閱者的資料列。

    • 針對交易式複寫,還有關於 XACT_ABORT 設定和在觸發程序中使用 COMMIT 與 ROLLBACK 陳述式的其他考量。如需進一步資訊,請參閱<交易式複寫考量>中的「觸發程序」一節。

  • 指令碼由訂閱者而非發行者的複寫執行。

    sp_addpublicationsp_addmergepublication@pre_snapshot_script@post_snapshot_script 參數可允許您指定在套用快照集之前和之後要執行的指令碼。如需詳細資訊,請參閱<在套用快照集的前後執行指令碼>。預存程序 sp_addscriptexec 可允許您在同步處理時執行指令碼。如需詳細資訊,請參閱<如何:在同步處理期間執行指令碼 (複寫 Transact-SQL 程式設計)>。

    這些指令碼通常用在管理工作,如在訂閱者端加入登入。如果在「訂閱者」端使用指令碼來更新應視為唯讀的資料,則管理員必須確定不會導致非聚合。

  • 交易式發行集之預存程序執行的複寫會在「訂閱者」端產生不同的結果。

    若您複寫預存程序的執行,程序定義會在訂閱初始化之後,複寫到訂閱者端;在發行者端執行程序時,複寫會在訂閱者端執行對應程序。如需詳細資訊,請參閱<在交易式複寫中發行預存程序執行>。

    若預存程序在訂閱者端執行其他動作,或者針對發行者以外的其他資料作業,則可能無法聚合。考慮使用執行計算的程序,然後根據此計算插入資料。若訂閱者已篩選,以至於訂閱者端的計算皆以其他資料為基礎,那麼插入訂閱者端的結果會有所不同,或者根本不會進行插入。

  • 條件約束違規或其他問題,使資料列無法在訂閱者端插入、更新或刪除。

    針對交易式複寫,違反條件約束會視為錯誤;若發生此情況,依預設會導致散發代理程式停止同步處理 (如需更多有關略過錯誤的資訊,請參閱<略過交易式複寫中的錯誤>)。針對合併式複寫,違反條件約束會視為衝突;這些衝突會記錄下來,但並不會導致合併代理程式停止同步處理。針對兩種複寫類型,若在某節點成功插入、更新或刪除,但在另一節點失敗了,則違反條件約束可能導致無法聚合。

    在發行資料表時,預設結構描述選項指定外部索引鍵條件約束以及檢查條件約束應使用 NOT FOR REPLICATION 選項集,建立在訂閱資料庫中。若您的應用程式需要不同的條件約束設定,請變更結構描述選項。如需詳細資訊,請參閱<如何:指定結構描述選項 (SQL Server Management Studio)>和<如何:指定結構描述選項 (複寫 Transact-SQL 程式設計)>。

請參閱

概念