Memos About Salesforce

Salesforceにハマってたこと!

Salesforce System.LimitException: Apex CPU time limit exceeded Not Only SOQL but also data insert

こんにちは、管理人の@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件)