技術ブログ / 読了 約 9 分

Pega 宣言的処理のコスト設計|前方連鎖と後方連鎖の使い分け

Declare Expression は便利だが、前方連鎖のカスケードは1つのプロパティ変更が広範な再計算を引き起こす。宣言的処理は「書けば動く」半面、実行コストが見えにくい。本記事は前方連鎖と後方連鎖、宣言的と手続き的の境界線を、性能と保守性の観点で整理する。

結論から:宣言的処理は「カスケードの広さ」で選び、前方/後方でコストの発生位置を決める

Pega の宣言的処理(Declare Expression / Declare OnChange / Declare Trigger)は、「値を書けば、あとは Pega が自動で保守してくれる」強力な仕組みです。合計金額、与信残枠、ステータスの派生値——こうした「他の値から導かれる値」を、手続きロジックで毎回計算・代入しなくても、宣言しておくだけで整合が保たれます。

しかし、この便利さには裏側があります。宣言的処理は**依存ネットワーク(何が何に依存しているか)**の上で動くため、ネットワークが広がるほど「1つのプロパティを変えると、どこまで再計算が波及するのか」が読みにくくなり、実行コストとデバッグ性を静かに蝕みます。

結論を先に言うと、判断の型はこうです。

「宣言的にするか手続き的にするか」はカスケード(波及)の広さと可読性で決める。宣言的にすると決めたら、前方連鎖か後方連鎖かで“コストを払う位置”(書き込み時か読み取り時か)を選ぶ。

なお、そもそも計算を宣言的ルール(Declare Expression)と手続き的ロジック(Data Transform / Activity)のどちらに書くかという置き場所の判断は、計算ロジックの置き場所(Declare Expression と Data Transform の使い分け)で扱います。本記事は「宣言的にする」と決めた後の、前方連鎖と後方連鎖のコスト設計に焦点を当てます。

前方連鎖と後方連鎖の使い分け 読み取り中心の値は前方連鎖で更新時に再計算・保持し、更新中心で読み取りが稀な値は後方連鎖で参照時に遅延計算する比較図。 その派生値へのアクセスは? 読み取り中心? / 更新中心・読み取りは稀? 読み取り中心 更新中心・読み取り稀 前方連鎖 更新時に再計算して保持 ・ソース変更でカスケード再計算 ・読み取りは即時(計算済み) ・コストは書き込み側に集中 ・依存網が広いと更新が重い 後方連鎖 参照時に遅延計算(goal-seek) ・読み取られた時に計算 ・書き込みは軽い ・コストは読み取り側に発生 ・多用すると読み取りが遅延 迷ったら「その値は何回読まれ、何回書かれるか」を数える
図:読み取り中心の派生値は前方連鎖で更新時に計算・保持し、更新中心で読み取りが稀な値は後方連鎖で参照時に遅延計算する。コストの発生位置(書き込み時か読み取り時か)が両者の本質的な違い。

宣言的処理とは何を自動化するのか

宣言的処理は、「どう計算するか」の手続きではなく「この値はこう定義される」という関係を宣言し、その維持を Pega に委ねる仕組みです。代表的なルールは 3 つです。

  • Declare Expression — あるプロパティを、他のプロパティから導かれる式として定義する。もっとも多用される宣言ルール。
  • Declare OnChange — あるプロパティが変わったら特定の処理(Activity 等)を起動する。
  • Declare Trigger — インスタンスの保存・削除などのイベントを起点に処理を起動する。

いずれも共通点は「起点の変化を Pega が監視し、自動で追従してくれる」ことです。手続き的に書けば「金額が変わったら合計を計算し直す」コードを呼び出し忘れる余地がありますが、宣言的ならその整合維持を Pega が肩代わりします。

問題は、この「自動追従」がどの経路で・いつ・どこまで走るのかが、依存ネットワークの広がりとともに見えにくくなる点です。ここを制御するのが、Declare Expression の計算モード——前方連鎖と後方連鎖です。

前方連鎖と後方連鎖 — コストはどこで払うか

Declare Expression には、値をいつ計算するかで大きく 2 つの考え方があります。どちらで動かすかは、Declare Expression ルールの Change Tracking タブ(Calculate Value 設定)で指定します。既定は前方連鎖に相当する「Whenever inputs change」です。

前方連鎖(forward chaining)

ソース(入力)が変わった瞬間に、対象(出力)を再計算する方式です(Change Tracking で「Whenever inputs change」を選んだ状態)。変更が起点となり、それに依存する値へ計算がカスケード(連鎖的に波及)していきます。たとえば Area が Length × Width、Volume が Area × Depth と定義されていれば、Length を変えるだけで Area→Volume まで自動で再計算が波及します。再計算された結果はプロパティ(クリップボード)に保持されるため、後続の読み取りは即座に済みます。

  • コストの位置 — 書き込み・更新時。ソースを変えるたびに、依存する値の連鎖が走る。
  • 向く場面 — 一度計算すれば何度も読まれる値(画面表示・レポートで頻繁に参照される派生値)。読み取りが多く更新が少ないほど有利。
  • リスク — 依存ネットワークが広いと、些細な 1 プロパティの変更が広範囲の再計算を誘発する。

後方連鎖(backward chaining)

対象の値が必要になった時に、はじめて計算する方式です(Change Tracking で「Whenever used」「When used if no value present」等を選んだ状態)。いわゆる goal-seek(Pega では Property-Seek-Value メソッド)による遅延評価で、値が要求されるまで計算を先送りします。ソース側のプロパティが変わっても、後方連鎖では自動での再評価は起きません。

  • コストの位置 — 読み取り(値が要求された)時。参照されなければ計算されない。
  • 向く場面 — 更新は頻繁だが読み取りは稀な値、あるいは特定の分岐でしか使われない値。書き込み側を軽くしたいとき。
  • リスク — 参照が多い経路で「Whenever used」を多用すると、読み取りのたびに計算が走り、画面応答やレポートが遅延する。

各計算オプションの厳密な挙動(キャッシュの有無・既定値・エッジケース)は Pega のバージョンによって差異がありうるため、設計を確定する前に利用中の版の公式ドキュメントと実機で確認してください。たとえば「Whenever used」は読み取りのたびに評価する一方、「When used if no value present」は値がなければ計算し以後はキャッシュを使う、といった違いがあります。本記事の核は「コストの発生位置で選ぶ」という判断の型です。

前方連鎖 / 後方連鎖 比較表

観点前方連鎖後方連鎖
計算のタイミングソース変更時(即時)対象の参照時(遅延)
コストが乗る操作書き込み・更新読み取り
結果の保持再計算して保持参照ごとに評価
向くアクセス傾向読み取り >> 更新更新 >> 読み取り/読み取りが稀
主なリスク依存網の広さで更新が重くなる多用で読み取りが遅延する
典型例画面常時表示の合計・残枠分岐でのみ使う判定値

宣言的か、手続き的か — カスケードの広さで切り分ける

前方/後方の前に、そもそも「宣言的にすべきか」という一段上の判断があります。同じ派生値は、Data Transform や Activity といった手続き的ロジックでも実現できます。両者は保守モデルが正反対です。

観点宣言的(Declare Expression / OnChange / Trigger)手続き的(Data Transform / Activity)
整合の維持Pega が自動保守開発者が明示的に呼び出す
実行の起点依存の変化に暗黙に追従フローやステップから明示的に実行
可読性依存網が広がると追いにくい実行順序が明示的で追いやすい
保守呼び出し忘れが起きない呼び出し漏れ・重複のリスク
向く場面カスケードが狭く、整合を常に保ちたい実行タイミングを明示制御したい

判断の軸は 「カスケードの広さ」と「可読性」 です。

  • 狭く閉じた依存関係(1 つの値が少数の入力から素直に導かれる)で、常に整合していてほしい → 宣言的が有利。呼び出し忘れの事故が構造的に起きません。
  • 波及が広い・計算順序を明示的に制御したい・タイミングが業務ロジックに強く依存する → 手続き的が有利。どの順で何が走るかがコード上で追え、デバッグしやすい。

宣言的処理は「書けば動く」半面、実行コストと副作用がコード上に現れないのが弱点です。依存網が広い領域を宣言だらけにすると、性能問題が起きたとき「どの変更が、どの再計算を、いくつ誘発しているか」を追うのが困難になります。

よくある失敗

宣言的処理でつまずくパターンは、経験上ほぼ次の 3 つに集約されます。

失敗1:前方連鎖の依存網が、全変更で再計算する

読み取り主体だからと前方連鎖を選んだのは正しくても、依存ネットワークが広く絡み合っていると、末端の 1 プロパティを変えただけで広範囲の再計算がカスケードします。入力項目の多い画面で「1 フィールド編集するたびに引っかかる」体感の重さは、たいていこれが原因です。依存の起点がどれだけ頻繁に変わるかを見積もらずに前方連鎖を広げると、更新コストが積み上がります。

失敗2:後方連鎖(goal-seek)の多用で、読み取りが遅延する

「書き込みを軽くできる」からと後方連鎖を多用すると、今度は読み取りのたびに計算が走ります。レポートや一覧のように同じ派生値を大量に・繰り返し参照する経路で後方連鎖を使うと、行数ぶんの遅延評価が積算され、応答が悪化します。後方連鎖は「稀にしか読まれない値」向けであって、常時参照される値には不向きです。

失敗3:宣言と手続きの混在で、計算順序を追えなくなる

同じデータに対して、あるフィールドは Declare Expression で、別のフィールドは Data Transform で、さらに OnChange で Activity を起動して…と混在させると、最終的にどの順で値が確定するのかが誰にも追えなくなります。加えて、Declare OnChange の Activity 内で、起動条件となったプロパティ(や Declare Expression の対象プロパティ)を書き換えると、意図しない連鎖や無限ループを招く——Pega 公式も「OnChange Activity の中で、その Activity を起動させたプロパティを更新してはならない」と明記しています。Declare Expression がデータページを参照する構成では、参照先データページのロード/リフレッシュ戦略ぶんのコストが評価に乗りうる点にも注意が必要です(Pega はデータページのリフレッシュを 1 インタラクションにつき最大 1 回に制限するため「評価のたびに毎回リロード」まではしませんが、初回ロードや参照自体のコストは残ります)。「宣言で自動保守されるはず」の値が、手続きロジックに上書きされて整合が崩れる——という不具合は、この混在から生まれます。

実装時の勘所

  • まず読み書きの頻度を数える。 「この派生値は 1 回の処理で何回読まれ、何回書かれるか」を見積もってから前方/後方を選ぶ。感覚で選ばない。
  • 依存ネットワークを図に起こす。 前方連鎖を採用する値は、依存の起点と波及先を一度可視化して、カスケードが想定より広くないか確認する。
  • 宣言と手続きの責務を分ける。 1 つのプロパティの確定経路は、宣言か手続きのどちらか一方に寄せる。両方から書かない。
  • データページ参照を含む宣言に注意。 Declare Expression の中でデータページを参照する場合、参照先データページのロード/リフレッシュ戦略とその発生頻度を見積もる(リフレッシュは 1 インタラクション最大 1 回に制限されるが、ロード自体のコストは残る)。

まとめ

  • 宣言的処理は「値を書けば整合が保たれる」強力な仕組みだが、依存ネットワークが広がると実行コストと副作用が読みにくくなる。
  • 宣言的か手続き的かは「カスケードの広さと可読性」で決める。 狭く閉じた整合は宣言的、波及が広く順序制御が要るなら手続き的。
  • 宣言的にすると決めたら、**前方連鎖=書き込み時にコスト(読み取り主体向き)/後方連鎖=読み取り時にコスト(更新主体・稀読み向き)**で、コストの発生位置を選ぶ。
  • 失敗は 3 つ——前方連鎖の依存網が全変更で再計算、後方連鎖の多用で読み取り遅延、宣言と手続きの混在で計算順序を追えない。この 3 つを避けるだけで、宣言的処理の設計は大きく安定する。

宣言的処理は、Pega の生産性を支える中核であると同時に、性能問題の温床にもなり得ます。設計の初期に「どこまで自動保守に委ね、どこを手続きで明示制御するか」を言語化しておくことが、後工程での性能改善という重い手戻りを防ぎます。

関連リンク

RELATED

関連記事

Pega Insights と Report Definition の使い分け|セルフサービス分析と運用レポートの線引き

「レポートは Report Definition で作るべきか、Insights でユーザーに任せるべきか」——ダッシュボード設計で必ず出る分岐です。統制と再利用が要る定型レポートはルール化し、アドホックな探索はセルフサービスに開く、が基本方針。本記事では両者のガバナンス差とデータソースの前提から、線引きの判断軸を示します。

記事を読む

Pega 監査証跡設計:フィールド監査・履歴・セキュリティ監査の使い分け

「何を、どこまで監査するか」は Pega のセキュリティ設計で最も判断が割れるテーマです。フィールド監査・ケース履歴・セキュリティイベントの使い分けと、監査のかけ過ぎが招く性能・容量問題の回避策を、LSA の視点で解説します。

記事を読む

Pega 連携の冪等性設計|リトライで二重処理を起こさないための判断

「リトライしたら二重に登録された」——連携で最も痛い事故のひとつです。キュープロセッサやネットワークのリトライは基本 at-least-once で、重複実行は前提として設計すべきものです。本記事では、冪等キー・重複検知・副作用の分離といった手法で、何度呼ばれても安全な連携をどう組むかを整理します。

記事を読む

Pega 導入のご相談はお気軽に。

Pega Customer Service / Pega Constellation UI / Pega Platform の各ソリューションについて、無料でご相談を承ります。