HANDLECOLLISIONS | NOHANDLECOLLISIONS

有效對象

Replicat

說明

在目標上套用 SQL 時,請使用 HANDLECOLLISIONS 和 NOHANDLECOLLISIONS 參數來控制 Replicat 是否嘗試解決重複記錄和遺漏記錄錯誤。在 Oracle GoldenGate 正在複製對這些表格所做的交易變更時,在初始載入來源表的資料載入目標表時,會發生這些錯誤,稱為衝突。當 Oracle GoldenGate 在載入完成後套用複製的變更時,HANDLECOLLISIONS 會為這些衝突提供含有錯誤處理邏輯的 Replicat。

您可以使用 HANDLECOLLISIONS 和 NOHANDLECOLLISIONS,方法如下:

前述方法可以合併。您可以指定全域衝突處理規則,然後在 MAP 敘述句中以不同的衝突處理規則覆寫該規則。MAP 規格一律會覆寫全域規格。

注意:整合式 Replicat 的錯誤處理不適用於 HANDLECOLLISIONS。Oracle 建議您使用精確的建立方法,而不是使用 HANDLECOLLISIONS。

HowHANDLECOLLISIONSWorks

下列範例說明 HANDLECOLLISIONS 的運作方式:

  1. 應用程式會更新來源 table1 中的記錄 A。

  2. 擷取會擷取更新。

  3. 應用程式會刪除來源 table1 中的記錄 A。

  4. 擷取會擷取刪除。

  5. Oracle GoldenGate 會從來源 table1 擷取起始載入資料,但不擷取記錄 A。

  6. Oracle GoldenGate 會套用初始載入 (不含記錄 A)。

  7. Replicat 嘗試套用記錄 A 的更新。

  8. 資料庫傳回「遺漏記錄」錯誤。

  9. Replicat 會嘗試套用刪除記錄 A。

  10. 資料庫傳回「遺漏記錄」錯誤。

在初始載入期間擷取的交易變更套用至目標表格之後,停用 HANDLECOLLISIONS,讓 Replicat 不會自動處理後續的錯誤。初始同步化後產生的錯誤表示異常情況,應由可決定解決方式的人員評估。例如,遺漏記錄錯誤可能表示來源系統上存在的記錄不慎從目標系統中刪除。

您可以透過下列方式關閉 HANDLECOLLISIONS:

避免遺漏資料欄值的可能解決方式

當資料庫預設不會記錄來源表格的所有資料欄值時,如果目標表格在 Replicat 嘗試將主要索引鍵更新轉換成插入時有 NOT NULL 限制條件,就會發生錯誤。您可以透過下列方式解決此情況:

如果資料庫預設包含所有資料欄,則 HANDLECOLLISIONS 必須使用 NOCOMPRESSUPDATES 和 NOCOMPRESSDELETES 才能正常運作。如果資料庫不支援 NOCOMPRESSDELETES,您必須使用 FETCHOPTIONS MISSINGCOLS。

如需有關 Oracle GoldenGate 起始載入方法的詳細資訊,請參閱關於使用起始載入擷取建立。

預設

NOHANDLECOLLISIONS

語法

HANDLECOLLISIONS | NOHANDLECOLLISIONS [_ALLOWPKMISSINGROWCOLLISIONS]
[THREADS (<threadID>[, <threadID>][, ...][, <thread_range>[, <thread_range>][, ...])]

HANDLECOLLISIONS

啟用碰撞處理。

_ALLOWPKMISSINGROWCOLLISIONS

如果對應的目標資料列不存在,請使用 HANDLECOLLISIONS 搭配 _ALLOWPKMISSINGROWCOLLISIONS 來略過主索引鍵 UPDATE 作業。

注意:略過作業可能會導致資料損毀。請參閱本主題中的「說明」。

NOHANDLECOLLISIONS

關閉碰撞處理。

THREADS (<threadID>[, <threadID>][, ...][, <thread_range>[, <thread_range>][, ...])

對指定的執行緒啟用 HANDLECOLLISIONS。在參數檔根層次的全域 HANDLECOLLISIONS 敘述句中使用時,指定繫線的 HANDLECOLLISIONS 都會啟用,無論這些繫線在哪個 MAP 敘述句中。在 MAP 陳述式的 HANDLECOLLISIONS 子句中使用時,只有該 MAP 陳述式會啟用 HANDLECOLLISIONS。

threadID[, threadID][, …]

指定繫線 ID 或以逗號分隔的繫線清單,格式為 threadID, threadID, threadID。

thread_range[, thread_range][, …]

以 threadIDlow-threadIDhigh 格式或以逗號分隔的範圍清單 (格式為 threadIDlow-threadIDhigh,threadIDlow-threadIDhigh) 來指定繫線範圍。

可以結合這些格式,例如 threadID、threadID、threadIDlow-threadIDhigh。

範例

範例 1

此範例會為參數檔中的所有 MAP 敘述句啟用 HANDLECOLLISIONS。

HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
MAP hr.dep, TARGET hr.dep;
MAP hr.country, TARGET hr.country;

範例 2

此範例會在部分 MAP 敘述句啟用 HANDLECOLLISIONS,同時停用其他敘述句。

HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
NOHANDLECOLLISIONS
MAP hr.dep, TARGET hr.dep;
MAP hr.country, TARGET hr.country;

範例 3

此範例顯示 MAP 陳述式內 HANDLECOLLISIONS 的基本用法。

MAP dbo.tcust, TARGET dbo.tcust, HANDLECOLLISIONS;

範例 4

此範例顯示全域使用和 MAP 層級的組合。MAP 規格會覆寫指定表格的全域規格。

HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
MAP hr.dep, TARGET hr.dep, NOHANDLECOLLISIONS;
MAP hr.country, TARGET hr.country, NOHANDLECOLLISIONS;

範例 5

在下列範例中,所有 MAP 陳述式都會全域啟用 HANDLECOLLISIONS,除了第一個 MAP 陳述式中的預設執行緒 0 與第二個 MAP 陳述式中的執行緒 3 之外。

HANDLECOLLISIONS
MAP fin.*, TARGET fin.*;
MAP sales.*, TARGET sales.*;
MAP orders.*, TARGET orders.*;
MAP scott.cust, TARGET scott.cust, NOHANDLECOLLISIONS;
MAP amy.cust, TARGET amy.cust, THREAD(3), NOHANDLECOLLISIONS;

範例 6

在此範例中,已全域啟用 HANDLECOLLISIONS,但已針對執行緒 3 關閉。其餘的執行緒 1、2 與 4 將處理衝突。

HANDLECOLLISIONS
NOHANDLECOLLISIONS THREAD(3)
MAP scott.emplyees, TARGET scott.employees, THREADRANGE(1,4, OID);
MAP scott.inventory, TARGET scott.inventory, THREADRANGE(1,4, OID);
MAP scott.cust, TARGET scott.cust, THREADRANGE(1,4, OID);

範例 7

在此範例中,已全域啟用 HANDLECOLLISIONS,然後全域停用執行緒 5 到 7 的執行緒。在第一個 map 敘述句中,所有繫線都會處理衝突,因為 HANDLECOLLISIONS 參數未指定繫線或範圍。在第二個 map 敘述句中,只有執行緒 4、8 與 9 會處理衝突,因為全域 NOHANDLECOLLISIONS 會套用至執行緒 5-7。

HANDLECOLLISIONS
NOHANDLECOLLISIONS THREADRANGE(5-7)
MAP scott.cust, TARGET scott.cust, THREADRANGE(4,9,OID), HANDLECOLLISIONS;
MAP scott.offices, TARGET scott.offices, THREADRANGE(4,9,OID);
MAP scott.emp, TARGET scott.emp, THREADRANGE(4,9,OID);
MAP scott.ord, TARGET scott.ord, THREADRANGE(4,9,OID);
MAP acct.*, TARGET acct.*;
MAP admin.*, TARGET admin.*;