こんにちは、管理人の@Salesforce.Zです。
掲題のようなエラーが出る場合
「Apex CPU time limit exceeded」エラーを回避するためのより効果的なコーディングを
考える必要になる
今回、その対策を共有します
目次
原因と対策
原因
Salesforce には、
CPU 使用率に基づくトランザクションのタイムアウト制限があり、
トランザクションが CPU 時間を過度に消費する場合、
トランザクションは長期実行トランザクションとしてシャットダウンになる。
カウントされるものとカウントされないもの
カウントされるもの
アプリケーションサーバーの CPU の使用を必要とするイベントのみをカウント
すべての Apex コード
Apex で公開されているライブラリ関数
ワークフローの実行
カウントされないもの アプリケーションサーバー CPU を使用するものにはカウントできないものがあるが、 これはプログラマーとしてはあなたがコントロールできないもの
レコードを取り出すデータベースに費やされる時間はカウントされない
コールアウトが戻るのを待つ時間もカウントされない。
コードのコンパイルが必要なときは制御しないので、カウントされない。
データベース操作 (例えば DML、SOQL)
SOSL
HTTP コールアウト
対策
List<Account> lstacc=[Select Id from Account limit 10000]; Set<Id> setIds=new Set<Id>(); for(Account a:lstacc){ //More CPU time for sure due to looping setIds.add(a.id); } //Using Map query saves CPU time //Fetching all account in map Map<id,account> aMap = new Map<id,account>([Select Id,Name from Account limit 50000]); //Creating list of accounts List<account> accList = aMap.values() ; //Creating set of ids Set<id> accIds = aMap.keySet() ;
cpu time limit exceededをわざと発生させる例
Account 300件登録
紐づくContactも300件登録
さらに
Contactに紐づく子レコード(ContactChildとする)を300件登録
さらに、
ContactChildに紐づく子レコードを300件登録
上記を匿名開発コンソールで実施すれば、cpu time limit exceededになります。
この例では、言いたいことは処理時間が長いもcpu time limit exceededになります。データ作成件数を減らしたら、解消になります。
//項目設定は略します。 insert AccountList //(300件) insert ContactList //(300件) insert ContactChildList//(300件) insert ChildOfContactChildList//(300件)