SalesforceにおけるCDC
(変更データキャプチャ)の
実装・活用法について
~そもそもコレどうやって使うの?一から学べる入門編~
株式会社ユー・エス・イー 畑本貴史
1
自己紹介
2
はたもと たかし
畑本 貴史
株式会社ユー・エス・イー
サービスデザイン事業部
カスタマーサクセス課 主任
経歴
 2010年~Salesforce開発者(Apex/Visualforceメイン)
 AIアプリコンテスト2018 優勝チーム(ロボホンズ)
 Lightning App Dev Champion
 Salesforce Developer Group Tokyo 運営メンバー ←New!
Summer’19のCDC関連アップデート
3
Summer’19(v46)のアップデート
https://releasenotes.docs.salesforce.com/ja-jp/summer19/release-
notes/rn_messaging_change_data_capture_section.htm
 Apex トリガでの変更イベントメッセージの処理
Apex 変更イベントトリガで、Lightning プラットフォームの変更イベントメッセー
ジを処理できるようになりました。変更イベントトリガは、データベーストランザ
クションが完了した後に非同期で実行されます。リソースを大量に消費するビジネ
スロジックは変更イベントトリガで非同期に実行され、トランザクションベースの
ロジックは引き続き Apex オブジェクトトリガで実行されます。変更イベントトリ
ガでは、変更の処理を分離することで、トランザクションの処理時間を短縮できま
す。
→CDCイベント発生時にApexトリガを起動できるように!
そもそも、CDC(変更データキャプチャ)とは?
CDCとは → 「Change Data Capture」の略
 データベース内の各トランザクションの更新内容を
レコード単位・項目単位でピンポイントで出力できる機能
(OracleDB、SQLserver等では標準実装)
CDCを使わない場合の差分取得
 DB内部の全レコードのキャッシュを取得
→過去のキャッシュと比較し更新差分を抽出
→膨大なリソース消費、リアルタイム処理は困難
 項目変更履歴から最新の差分を抽出
→SOQLの集計関数(Max)で取得しきれない場合はやはり外部DBで処理
4
SalesforceのCDC仕様①
5
 ストリーミングAPIの一種
外部システムに対して、「イベントバス」を中継し
複数の端末・サーバにプッシュ通知を送受信するAPIとして実装
Salesforce
Platform
Server
PC
Mobile
Event
Bus
ストリーミングAPIの一覧
6
ストリーミングAPIで取り扱うイベント一覧
汎用イベント
プラットフォーム
イベント
PushTopic
変更データ
キャプチャ
実行
タイミング
任意
(Apex, SOAP/REST)
任意
(Apex,
フロー/プロセス)
DML発生時
(事前に指定した
条件のみ)
DML発生時
(すべて)
通知内容 任意のテキスト
事前に定義した項目に
任意の値を登録
クエリで指定した
項目の値
CDCが検知した
差分項目すべて
対象データ
任意(呼び出し元で
設定)
任意(呼び出し元で
設定)
クエリで指定した
検索条件に合致 すべてのレコード
SalesforceのCDC仕様②
7
 CDCのイベント情報は専用オブジェクトに格納される
例:取引先 (Account) を更新する →
CDCオブジェクト“AccountChangeEvent”が登録される
※イベント監視では直近3日間のレコードが追跡できる
 CDC発生時には、その更新内容がSalesforce外部に自動通知される
通信形式:REST
URL形式:“/data/AccountChangeEvent”
CDCを試してみる
8
デモ:Salesforce → MuleSoft AnyPointへのCDC連携
 Salesforce:Accountの変更データキャプチャ起動設定
 Mulesoft:変更データキャプチャ受信設定
参考:SalesforceのCDCとMuleSoft Anypoint Platformを組み合わせた
イベント駆動型のシステム連携 (@ykibeさん)
https://qiita.com/ykibe/items/52d5e724b7ceb9831fcd
SalesforceのCDCは何のためにあるのか?
9
イベント駆動型アーキテクチャに基づく実装
 連携元の更新状況が自動的に連携先に反映される(Push型)
→(準)リアルタイム連携の実現
 連携1回あたりのデータ量が最低限、コールバックなし
→連携処理の負荷軽減(疎結合)
その他従来手法との比較
 連携先からの定時ポーリング(Pull型)
→リアルタイム性の欠如、場合によっては大量データの一括処理発生
 連携元⇒連携先へのリアルタイムデータ連携処理
→トランザクションへの負荷増大(密結合)
本題:Apexトリガを試してみる
10
デモ:AccountのCDCイベント「AccountChangeEvent」にトリガ設定
 CDCイベント発生時のデバッグログ取得設定
 CDCイベントへのApexトリガを設定
通常のApexトリガと何が違うか?①
11
 「ChangeEvent」に対するトリガ
→CDCの発生元になったオブジェクトへの更新処理とは非同期で動作する
 既存のトリガ・自動プロセスによるガバナ制限に抵触しない
 CDCトリガから発生元レコードへの再更新処理も可
 直接起動条件は「after insert」のみ
→Triggerクラスの「isInsert()」「isUpdate()」等のメソッドへは判別不可
→「Eventbus.ChangeEventHeader」からCDC起動条件を取得
通常のApexトリガと何が違うか?②
12
「Eventbus.ChangeEventHeader」の主要パラメータ
 entityName:発生元オブジェクト名
 changeType:発生時処理(Insert, Update, Delete, Undelete)
 recordIds:発生元レコードのID(原則1件)
 changeorigin:発生時のアクセス経路
(API経由の更新 or Lightning Experience)
 nulledFields:Update時にNullに更新された項目一覧
Etc…
通常のApexトリガと何が違うか?③
13
「Trigger.new」から得られる値
→発生元のイベントで登録・変更された値のみ連携される
(項目定義は発生元レコードとほぼ同じ)
 Insert:入力されたすべての値
 Update:更新差分のある値のみ
 Delete:なし
 Undelete:すべての値(Insertと同等)
Trigger.newから発生元レコードIDは取れないので、
前述のChangeEventHeader.recordIdsから取得
通常のApexトリガと何が違うか?④
14
実装上の注意事項
 バッチサイズ「2,000件」
→一括処理を行った場合、ガバナ制限に抵触しやすい
(非同期ガバナ制限が適用されるため負荷耐性は高いが)
 発生元イベントとは非同期で実行される
→トリガでエラーが発生しても、発生元レコードはロールバックしない
 入力規則の代わりに使うことはできない
 必要な処理が一部起動しないことにより、データの整合性が乱れる可能性
CDCトリガは何のために使うのか?
15
イベント駆動型アーキテクチャの概念をSalesforce内部に持ち込む
大規模環境の運用におけるトランザクション負荷の緩和
 参照関係・主従関係に関連するクロスオブジェクト処理
 複数のトリガ・自動プロセス構築による連動処理
Apex処理が必要なリアルタイム連携処理の実装
 JSON形式以外へのデータ整形を行い外部システムへPush
 Salesforce⇔外部システムの双方子同期処理を起動
参考資料
16
 Change Data Capture Developer Guide
https://developer.salesforce.com/docs/atlas.en-
us.change_data_capture.meta/change_data_capture/
 Trailhead:変更データキャプチャの基礎
https://trailhead.salesforce.com/ja/content/learn/modules/change-data-capture
 ストリーミング API 開発者ガイド
https://developer.salesforce.com/docs/atlas.ja-jp.api_streaming.meta/api_streaming/
 Trailhead:プラットフォームイベントの基礎
(モジュール:イベント駆動型ソフトウェアアーキテクチャの理解)
https://trailhead.salesforce.com/ja/content/learn/modules/platform_events_basics
ご清聴ありがとうございました!
17

SalesforceにおけるCDC(変更データキャプチャ)の実装・活用法について