Salesforceデベロッパーにおける永遠の課題(?)である
トリガとワークフロールール(以後、WFと略す)の共存について書いてみる。
まずは両者のメリット・デメリットを記述する。
WF
[メリット]・ノン開発のカスタマイズにより、簡単かつスピーディーにビジネスロジックを構築可能。
[デメリット]
・対応できないビジネスロジックが存在する。
・項目自動更新では数式のコンパイルサイズに制限がある。
トリガー
[メリット]・WFよりビジネスロジックの自由度が高く、カスタマイズのみではできない複雑なビジネスロジックでも対応可能
[デメリット]
・ビジネスロジックの再構成に開発・テストコード構成・デプロイが必要になるため、フレキシブルな対応がしづらい。
・あらゆるDML操作によって起動する可能性があるため、綿密な設計が必要になる。
(WFでも同様だが、ビジネスロジックが複雑になりがちで、他レコードのDML操作も可能なトリガでは特に注意が必要。)
・トリガ独自のガバナ制限(SOQLで10万件以上の母数のレコードを検索するときにインデックス項目が必要等)
また、両者を併用することで以下のデメリットが存在する。
・以下URLに記載されるトリガーとWFの実行順序を考慮した設計が必要になる。
例えば、トリガーの処理結果を受けてWFの項目自動更新処理が行われた場合、
それによって再度トリガー処理が走るという事象を考慮した設計が必要になる。
上記事項をまとめると、
「WFは手軽に構成できるビジネスロジックであるが、複雑なビジネスロジックに対応できず、
トリガーは手軽ではないが複雑なビジネスロジックに対応可能で
両者を組み合わせると、あらゆるDML操作によって起動するトリガ処理と、
WFとトリガーの実行順序を考慮した難解な設計作業が必要になる。」
ということ。
よってSalesforceにおける設計においては以下のような設計方針が存在する。
これは、ビジネスロジックの棄却はしない前提で、
現実的なSalesforce導入において「混在したWFとトリガのロジックを全て見渡すことは極めて困難」
という立ち位置での設計方針である。
1. 各オブジェクトに対するビジネスロジックの構成はWFかトリガーのどちらかに寄せる。
→WFとトリガーの実行順序を考慮した複雑な設計が不要になり、ロジックが見えやすくなる。
2. トリガーによる他レコード更新は可能な限り行わない。
→他レコードの更新により、他レコードのWF・トリガーが走るというトリガーリレーを防ぐことができ、ロジックが見えやすくなる。
3. トリガの作成というソリューションを避ける
(インラインVFやカスタムボタンによる手動起動)
→ロジックの見通しがしづらいトリガ自体をなくすことができるが、運用が回りづらくなる危険性もある。
それぞれについて解説する。
1の場合は、ビジネスロジックが簡単な場合はWFに寄せれるし、
複雑なロジックが存在し、簡単なロジックが不変な場合(ビジネスロジックの変更がない)は
トリガーに寄せれるということになる。
2の方針は、トリガーの最悪なシナリオは複雑なビジネスロジックによる自レコードの更新よりも
例え簡単なビジネスロジックでも他レコードの更新の方がリスクが高い為である。
トリガーリレーが走るとロジック上問題がなくとも、
SOQL、DML、ステップ数等のガバナ制限に抵触する可能性が増えてしまう。
3の構成案としては
例えば、参照関係における子オブジェクトの集計や積上集計項目数の枯渇で、
Apex開発での集計をする場合にはトリガではなく、
・標準画面のインラインVFページにボタンを置いて集計処理をさせる。
・OnClickJS等のカスタムボタンで集計処理をさせる。
・短い時間間隔によるバッチ集計処理をさせる。
といった実装をするということ。
「オペレーションを簡素にする」「即時反映」という絶対要件がある場合は
このパターンは使えない。
いずれも個人的な意見・対応案ではあるけれど、
気軽にビジネスロジックやERの変更が可能なSalesforceにおいて「保守性」を担保する実装方針を
デベロッパーは意識すべきで、トリガとWFの共存という課題は特に考慮しておかないとダメなんじゃないかなーと。