フロー制限を回避する
学習の目的
この単元を完了すると、次のことができるようになります。
- フローのトランザクションあたりの制限を特定する。
- フローの制限を超える可能性がある大量のレコードへのアクセスを回避する。
- フローの制限を超える可能性があるループの使用を回避する。
フローを制限内に収める
フローは非常に強力ですが、その力には制限があります。Salesforce はマルチテナントインフラストラクチャ上で実行されています。これは、組織がほかの組織とサーバーリソースを共有していることを意味します。1 つの組織がサーバー上のほかの組織に影響を与えないように、Salesforce はさまざまな方法でフローとコードに制限を設けています。Salesforce では、これらをガバナ制限と呼びます。
フローには特定のシナリオや条件に応じた考慮点がいくつもありますが、特に把握しておくべきなのはトランザクションあたりの制限です。これらの制限はすべてのフローに適用され、うっかりすると簡単に超過してしまい、警告なしにどのフローでも強制的に停止させる可能性があります。「トランザクションあたり」であるのは、1 つのトランザクション内で発生できる処理の数を制限するためです。
では、トランザクションとは正確には何でしょうか。フローにおけるトランザクションを理解するために、2 本の列車に例えて考えてみましょう。1 本目の列車は急行列車で、停車せずに地点 A から地点 B まで進みます。2 本目の列車は、各駅で乗客を乗せるために停車します。フローは、1 本目の列車のように 1 つのトランザクション内で中断されることなく実行されることがあります。また、2 本目の列車のように、フローが画面要素や [Wait for Conditions (条件の待機)]、[Wait for Amount of Time (一定期間待機)]、[Wait Until Date (次の日付まで待機)] のいずれかの待機要素に到達して停止する場合もあります。フローが停止すると、現在のトランザクションは終了します。停止後は、新しいトランザクションが開始されます。1 回の列車の旅が駅によって分割されるように、1 つのフローも途中の停止によって複数のトランザクションに分割されます。
次に、フローやほかの自動化を中心にトランザクションがどのように分割されるかについて、いくつかのシナリオで例を見ていきましょう。[Next (次へ)] ボタンと [Previous (前へ)] ボタンを使用してシナリオを確認していきます。
フローでよく発生するトランザクションあたりの制限の代表例を次に示します。
|
制限の種別
|
説明
|
制限
|
|---|---|---|
|
SOQL Salesforce Object Query Language (SOQL) クエリは、Salesforce 組織のデータベースから特定のレコードデータを取得するための要求です。
|
SOQL クエリは次の要素によって発生します。
各要素は 1 回のクエリを発生させます。 |
|
|
DML Data Manipulation Language (DML) ステートメントは、Salesforce 組織のデータベース内のレコードを追加、編集、または削除するコマンドです。
|
DML ステートメントは次の要素によって発生します。
各要素は 1 つのステートメントを発生させます。 |
|
CPU |
トランザクションの実行に要する時間です。 |
1 トランザクションあたり 10 秒の CPU 処理時間 |
かなり大きな数値に見えます。「この制限に近づくことは決してないだろう」と思うかもしれません。ですが、思っているよりも簡単に近づいてしまいます。次に、フロー作成者がこれらの制限に到達しがちな一般的な原因と、それを防ぐためにできることを見ていきましょう。
大量のレコード
1 つのオブジェクト内のレコード数が数万件に達するには、いくつかの状況があります。1 つは、大規模なリードデータベースをアップロードする場合です。もう 1 つは、それぞれに複数の取引先責任者が関連付けられた取引先が、数千件ずつ徐々に蓄積していく場合です。多数のレコードが存在しても問題はなく、データベースが大規模であるだけではフローエラーは発生しません。SOQL 制限や DML 制限に到達しないようにするには、フローが処理するレコード数を制限する必要があります。
SOQL 制限や DML 制限に到達しないように、検索条件を使用して、フローが取得および更新するレコード数を最小限に抑えます。このバッジの前半でインストールしたパッケージに含まれている [Uncheck Contacted This Quarter (今四半期に連絡済みをオフにする)] フローを見てみましょう。
![決定要素に [Yes (はい)] パスと [No (いいえ)] パスがある [Uncheck Contacted This Quarter (今四半期に連絡済みをオフにする)] フロー。[Yes (はい)] パスには「Uncheck Contacted (連絡済みをオフにする) (連絡済みをオフにする)」という名前の [Update Records (レコードを更新)] 要素が含まれており、[No (いいえ)] パスには要素が含まれていません。](https://res.cloudinary.com/hy4kyit2a/f_auto,fl_lossy,q_70/learn/modules/flow-implementation-1/avoid-flow-limits/images/ja-JP/5a401ae1db010b7769052d473a110d8a_i.29.png)
スケジュールトリガーフローは四半期ごとに実行するようには設定できないため、このスケジュールトリガーフローは毎日実行されます。決定要素で現在の日付が四半期の初日かどうかを確認し、初日である場合は、[Update Records (レコードを更新)] 要素が組織内のすべての取引先責任者の [Contacted This Quarter (今四半期に連絡済み)] チェックボックスをオフにします。この処理は、すでにチェックがオフになっているレコードに対しても実行されます。このフローは、組織に 10,000 件を超える取引先責任者が存在する場合は失敗します。[Contacted This Quarter (今四半期に連絡済み)] がオンになっている取引先責任者のみを更新するように、フローを更新しましょう。
- [Uncheck Contacted This Quarter (今四半期に連絡済みをオフにする)] フローで、[Uncheck Contacted (連絡済みをオフにする)] 要素をクリックします。
- [Filter Contact Records (取引先責任者レコードの絞り込み)] セクションで、[Condition Requirements to Update Record (レコードを更新する条件の要件)] を [All Conditions Are Met (AND) (すべての条件に一致 (AND))] に変更します。
- [Field (項目)] で [Contacted This Quarter (今四半期に連絡済み)] を選択します。
- [Operator (演算子)] が [Equals (次の文字列と一致する)] に設定されていることを確認します。
- [Value (値)] で [True] を選択します。
- フローを保存します。
この変更により、更新される取引先責任者の数が 10,000 件のレコード制限を下回るはずです。さらに、フローが処理する作業量が減るため、実行速度も向上します。
同様の検索条件は、[Get Records (レコードを取得)] 要素や、レコードトリガーフローの開始要素にも設定できます。
ループ
ループは、フローでレコードのコレクションを反復処理し、各レコードを 1 件ずつほかの要素に渡して実行できる強力な要素です。ループ要素は、ループ内のレコードごとに 1 回ずつ実行されるため、ループが数件を超えるレコードを処理していて、かつ [Get Records (レコードを取得)]、[Create Records (レコードを作成)]、[Update Records (レコードを更新)]、または [Delete Records (レコードを削除)] 要素が含まれている場合、100 件の SOQL クエリ制限や 150 件の DML ステートメント制限にすぐ到達する可能性があります。
これらの制限に到達しないように、[Get Records (レコードを取得)]、[Create Records (レコードを作成)]、[Update Records (レコードを更新)]、または [Delete Records (レコードを削除)] 要素をループの中に配置しないでください。その代わりに、これらの要素はループの外に配置します。
- Get Records (レコードを取得): ループの前
- Create Records (レコードを作成)、Update Records (レコードを更新)、Delete Records (レコードを削除): ループの後
次の例を見てみましょう。[Clone Opp with Products (商品付き商談をコピー)] フローは、商談とその商品をコピーします。
![[Get Records (Opp) (レコードを取得 (商談))]、[Assignment (割り当て)] (新しい商談の組み立て)、[Create Records (Opp) (レコードを作成 (商談))]、[Get Records (Opp Product) (レコードを取得 (商談商品))]、および [Assignment (割り当て)] と [Create Records (Opp Products) (レコードを作成 (商談商品))] を含むループを備えたフローキャンバス。](https://res.cloudinary.com/hy4kyit2a/f_auto,fl_lossy,q_70/learn/modules/flow-implementation-1/avoid-flow-limits/images/ja-JP/bd6e8552b9109895b5b570686a7b7c87_i.30.png)
このフローでは、商談の値を取得し (1)、割り当て要素を使用して (2) レコードの値にいくつか変更を加え、その変更後の値を使ってコピーを作成します (3)。フローは、商談に関連付けられた各商品についても同じ処理を行う必要があるため、ループ要素を使用して (4)、元の商談商品のそれぞれを処理します。ループでは、割り当て要素も使用して (5)、各商談商品の OpportunityId をコピーした商談の ID に設定します。(このフローでは、元の商談商品にこれらの変更を保存しませんので安心してください。)
その後、ループ内で [Create Records (レコードを作成)] 要素を使用して (6)、新しい商談商品を作成します。この [Create Records (レコードを作成)] 要素は、ループ内の各商品ごとに 1 回の DML ステートメントを実行します。商談に多数の商品が含まれている場合や、フローがほかの DML ステートメントを含む大きなトランザクションの一部である場合、トランザクションが 150 件の DML ステートメントを超えて、このフローは失敗します。このようなシナリオは起こりにくいかもしれませんが、発生する可能性はあります。これらすべての DML ステートメントを 1 回に減らせたほうが、はるかに安全ではないでしょうか。
[Create Records (レコードを作成)] 要素をループの外に移動しましょう。変更後の商談商品コピーを格納するためのレコードコレクション変数を作成します。次に、割り当て要素を更新して、現在の商談商品の変更後の値をその新しいコレクションに追加するようにします。最後に、[Create Records (レコードを作成)] 要素で、ループの後にコレクション内のすべてのコピーを作成できます。
- [Clone Opp with Products (商品付き商談をコピー)] フローで、変数を作成します。
- API 参照名:
newOppProds - データ型: レコード
- Allow multiple values (collection) (複数値を許可 (コレクション)): 選択
- Object (オブジェクト): Opportunity Product (商談商品)
- [Set Current Line to New Opp (現在の行を新しい商談に設定)] 要素を編集し、割り当て行を追加します。
- Variable (変数): newOppProds
- Operator (演算子): Add (追加)
- Value (値): [Current Item from Loop Opp Products (ループ Opp Products の現在の項目)] > [Entire Resource (リソース全体)]
- [Create Opp Prod (商談商品を作成)] 要素の上にカーソルを置き、
をクリックします。
-
[要素を切り取り] を選択します。
- [After Last (最後の項目の後)] パスで、
の上にカーソルを置きます。アイコンが
に変わったら、クリックします。
- [Create Opp Prod (商談商品を作成)] 要素を編集し、次の設定を変更します。
- How Many Records to Create (作成するレコード数): Multiple (複数)
- Record Collection (レコードコレクション): newOppProds
- フローを保存します。

これで、フローは各商談商品を順にループ処理し (4)、それぞれで割り当て要素 (5) が現在の商談商品の値を変更して、その変更後の値を newOppProds コレクションに追加します。次に、ループの後に配置された [Create Records (レコードを作成)] 要素 (6) が、newOppProds コレクション内のすべての商談商品を作成します。これらはすべて、1 つの DML ステートメントで実行されます。
別の自動化によって開始されるフロー
フローが別の自動化によって開始された場合、そのフローは最初の自動化のトランザクションの一部として実行されます。前述のガバナ制限はすべてトランザクションあたりの制限であるため、ほかの自動化によって実行された処理も、それらすべてのトランザクションあたりの制限に含まれます。
たとえば、Pyroclastic の組織には、処理に 9 秒の CPU 時間を要する複雑な Apex クラスがあります。その後、その Apex クラスが自動起動フローを呼び出します。フローの実行に 2 秒の CPU 時間がかかるため、トランザクション全体が 10 秒の制限を超え、フローは Apex クラスとともに失敗します。Apex クラスに SOQL クエリ、DML ステートメント、取得されるレコード数、または影響を受けるレコード数が多すぎる場合も、フローは失敗します。
この制限を回避する最善の方法は、自動化をできる限り効率的にすることです。Apex クラスの実行に 9 秒かかっている場合、簡素化や改善が可能である可能性が高いです。(9 秒は Apex クラスとしては長い時間です。) 9 ~ 10 秒かかるフローについても同様です。それでも解決しない場合は、[Wait for Conditions (条件の待機)]、[Wait for Amount of Time (一定期間待機)]、または [Wait Until Date (次の日付まで待機)] のいずれかの待機要素を追加して、新しいトランザクションを開始します。
習得度チェック
次の質問に答えて、フローの制限を回避するための知識を確認してください。
このサンプルツールは簡単な自己診断テストで、採点されるものではありません。各問題を読み、正しいと思う解答をクリックしてください。[Submit (送信)] をクリックすると、選択した回答が正解か不正解かと、その理由が示されます。最後まで進むと、解答を確認するか、問題に再解答できます。
