Heroku Connect の重複レコードの問題
最終更新日 2022年12月01日(木)
Table of Contents
Heroku Connect では、読み取りと書き込みに別々のスレッドを使用します。読み取り/書き込みマッピングに一意識別子がない場合、重複したレコードが作成される可能性があります。この記事では、このような状況とそれを防ぐ方法について説明します。
シナリオ
次のような場合、重複したレコードが作成されます。
- Heroku Connect が新しいレコードを Salesforce に書き込みます。
- 書き込みスレッドが新しい Salesforce ID (
sfid
) を Postgres に書き戻す前に、別のスレッドが Postgres へのレコード再同期を開始します。 - 変更を Salesforce から同期するとき、Heroku Connect はその Salesforce ID によってレコードを照合しようとします。この例では Salesforce ID が使用できないため、一意外部識別子を使用した照合にフォールバックします。
sfid
も一意外部識別子も使用できない場合、Connect は新しく、重複したレコードを Postgres に作成します。元のレコードのsfid
は設定されないままです。
一意性の保証による重複防止
Salesforce でオブジェクトにカスタムフィールドを追加し、一意識別子として設定します。この識別子は、重複したレコードの作成を防ぎます。さらに、設定された一意外部 ID を使用して、新しく挿入された行を外部テーブルから確実に参照することもできます。
一意識別子は Salesforce ID のエイリアスとして扱ってください。変更または再利用はせず、一意性を保証する生成メカニズムを選んでください。
Postgres の整数シーケンスは一意性が保証されないため、使用しないでください。Heroku Connect データベースの ID フィールドは一意識別子として使用しないでください。これらの数値は、設定を新しいデータベースにインポートしたり、テーブルをリロードしたりするとリセットされる可能性があります。
自動インクリメントフィールドは一意識別子に使用しないでください。
レコードを最初に INSERT
するときに、グローバルまたはユニバーサル一意 ID (GUID または UUID) などの一意の値を、この一意識別子フィールドに設定します。この戦略によって、Postgres で新しく作成されるレコードの一意性が保証されると同時に、オブジェクト間の関係が確立されます。gen_random_uuid()
を使用して生成できるランダム UUID を使用することをお勧めします。
gen_random_uuid()
の使用には pgcrypto
拡張機能の有効化 (CREATE EXTENSION IF NOT EXISTS pgcrypto;
) が必要です。
再挿入されたレコード
一意識別子を使用していても、Salesforce のレコードを Heroku Connect 経由で同期した直後に削除した場合は、重複したレコードが作成される可能性があります。この状況はまれにしか発生しませんが、Salesforce のレコードを Heroku Connect 経由で同期した直後に削除することはお勧めできません。削除する前に少なくとも 10 分間は待ってください。詳細は、「再挿入されたレコード」を参照してください。