PKカラムの値を一括して+1するような処理がソース側で行われている可能性があります。(主キー一括更新)
次のようなテーブルがあるとします。
TESTテーブル
ID(PK) NAME
1 A
2 B
3 C
こうしたテーブルに対して
UPDATE TEST SET ID=ID+1
のようなトランザクションが実行されますと、ソース側では
ID(PK) NAME
1->2 A
2->3 B
3->4 C
のように値が変更されます。
しかし、ログ上では
UPDATE TEST SET ID=2 WHERE ID=1
UPDATE TEST SET ID=3 WHERE ID=2
UPDATE TEST SET ID=4 WHERE ID=3
のようにトランザクションが分解されて、ターゲット側へ転送されます。
一意制約がある環境では、上記のようなトランザクションは実行時にORA-00001: 一意制約でエラーとなりますが、条件を指定した一括更新では受け入れられます。
しかし、SharePlexでは、1行SQLで複数行を処理するようなトランザクション処理はできないため、本事象が発生しえます。
状況的には UPDATE WITH CASEの際と似たような挙動となります。
TESTテーブル
ID(PK) NAME ID(PK) NAME
1->2 A ==========> 1->2 A ※この時点でPK列の2が重複するので一意制約違反
2->3 B 2
3->4 C 3
この後 ソートとターゲットで異なる状態でDMLによる更新時に 制約違反(ORA-00001)やデータが見つからない(ORA-01403) 状況が生じえます。
□一時的な制約の削除
移行目的の場合、一時的にターゲット側の一意制約を削除することで解決できます。
移行までの間に他のアプリから更新がないという前提状態が保たれ、ターゲットでのすべての更新はソースから転送されるSharePlexによる反映のみという状態において、一意制約を確保しなければならない理由は少ない状態です。
移行タイミングで、他のトリガーの有効化の処理等と一緒に制約の再設定ができます。
・ PKが存在しないことによるパフォーマンス上の懸念事項
ソース側でPKが存在し、ターゲット側でPKが存在しない場合の問題点として、PKのみによる行特定に疑念が発生するということがあげられます。
前述の例でいえば、IDが1の行がIDが2として更新された瞬間は、ID=2の列が2つあることになります。
この場合、PKがある状態でもあえてSharePlexの一意キーの定義の機能を使用することにより、PKと一つ以上の列を組み合わせて、予防的に意図しない行への更新になってしまうことを防ぐことができます。
キー定義の構文
キー定義を作成するには、ソースオブジェクトの後に空白文字を入力し、次の構文(かっこを含む)を使用します。
src_owner.table !key (column_list)
前述の説明である、ID列とNAME列を使用するには
OWNER.TEST !key(ID,NAME)
というようにconfigに対象テーブルを記述します。
・キー定義機能を使用する場合のインデックスの整備
ターゲット側でPKを一時的に削除し、SharePlexによるキー定義の機能を使用してレプリケーションする場合、適切なインデックスが存在しないため、キー定義に指定する列のインデックスを、指定する列を指定した形で作成します。
キー定義については、マニュアルの該当箇所をご参照ください。