Salesforce では、一度に特定の数のステートメント/レコードを処理または実行できます。 DML ステートメント、Apex クラスなどの実行または処理にはいくつかの制限があります。これらの制限は、ガバナー制限として知られています。このチュートリアルでは、ガバナーの制限とは何か、およびその処理方法について説明します。また、Salesforce Apex は、コールアウト、Apex クラス、Lightning Web コンポーネント、SOSL および SOQL ステートメントに関連する制限を知るための「Limit」クラスを提供します。
ガバナーの制限
Alish と Subash の 2 人が Salesforce 組織を使用しているシナリオを考えてみます。 Alice は、1 回のトランザクションで 1,000 個の DML ステートメントを処理または実行したいと考えています。並行して、Subash は一度に 5000 レコードをロードしたいと考えています。並行して行うと、Salesforce は受け入れず、多忙になります。したがって、ガバナーの制限が明らかになります。この場合、Alish は一度に 100 DML を処理でき、Subash は一度に 500 レコードを処理できます。 AsynchronousBatch Apex を使用して、各トランザクションを邪魔することなく個別のスレッドで各トランザクションを実行し、タスクを完了することができます。
基本的に、Salesforce のガバナー制限は、複数のトランザクションでの処理と実行を制限します。 「トランザクションごとの Apex 制限」は各トランザクションをカウントし、「サイズ固有の Apex 制限」はコードのサイズを扱います。 Salesforce は、同期プロセスと非同期プロセスの 2 つのプロセスをサポートしています。同期処理では Apex スクリプトを一度に実行し、非同期処理では Apex スクリプトを複数のジョブに分割して実行します。
許可された制限
さまざまなシナリオの制限数について説明しましょう。
- 同期 Apex では 100 個の SOQL クエリを処理/実行でき、非同期 Apex では 200 個の SOQL クエリを処理/実行できます。
- 同期 Apex と非同期 Apex の両方で、SOQL クエリから返されるレコードは 50,000 件のみです。
- Database.getQueryLocator() を使用すると、同期 Apex と非同期 Apex の両方で一度に 10,000 しか返されません。
- どちらのシナリオでも、発行される SOSL クエリの数は 20 です。
- 同期 Apex の処理に必要なヒープサイズは 6 MB です。非同期 Apex の場合、必要なヒープサイズは 2 倍になり、12 MB になります。
- 同期 Apex で許容される最大 CPU 時間は 10,000 ミリ秒で、非同期 Apex では 60,000 ミリ秒です。
- 両方の Apex の実行に許可される時間は 10 分だけです。
- どちらの場合も、100 人の受信者に対して 10 個の sendEmail() メソッドしか使用できません。
- Apex クラスまたは Apex トリガーに存在する文字は、100 万以内である必要があります。
- Batch Apex (非同期) では、サイズは 200 です。「Database」クラスの QueryLocator() は、トランザクションごとに 5,000 万レコードを返します。
- 5 つの Apex ジョブのみがキューまたはアクティブになります。
LIMIT クラスの例:
Apex は、「LIMIT」クラスでガバナー制限を指定できます。このクラスは、ガバナーの制限を通知するいくつかのメソッドを提供します。いくつかのガバナー制限を表示する次の例を見てみましょう。
System.debug('処理可能な集計クエリ数:'+ Limits.getLimitAggregateQueries());
System.debug('処理可能なWebサービス文数:'+ Limits.getLimitCallouts());
System.debug('処理できるレコード数:'+ Limits.getLimitDmlRows());
System.debug('呼び出せるDML文の数:'+ Limits.getLimitDmlStatements());
System.debug('総メモリ量: '+ Limits.getLimitHeapSize());
System.debug('発行可能な SOQL クエリの数: '+ Limits.getLimitQueries());
System.debug('発行可能レコード数:'+ Limits.getLimitQueryRows());
System.debug('発行できる SOSL クエリの数: '+ Limits.getLimitSoslQueries());
出力:
「LIMIT」クラスにある「dome」メソッドを使用して、返される DML ステートメント/行の数を確認することもできます。
- Limits.getDMLStatements() インスタンスで使用される DML ステートメントの合計を返します。
- Limits.getDMLRows() DML ステートメントによって返される行の総数を返します。
- Limits.getCpuTime() 現在のトランザクションの CPU 使用時間をミリ秒単位で返します。
使用例:
「WorkOrder」オブジェクトから 2 つのレコードを返す SOQL クエリを書きましょう。その後、「delete」DML を使用してこれら 2 つのレコードを削除します。
System.debug('DML ステートメント:'+Limits.getDMLStatements());System.debug('Rows:'+Limits.getDmlRows());
System.debug('CPU 時間'+Limits.getCpuTime());
// WorkOrder オブジェクトから 2 行を選択する SOQL クエリ
List
//delete DML を使用して 2 つの行を削除します
アカウントを削除します。
System.debug('**SOQL 後:**');
System.debug('DML ステートメント:'+Limits.getDMLStatements());
System.debug('Rows:'+Limits.getDmlRows());
System.debug('CPU 時間'+Limits.getCpuTime());
出力:
この例では、DML ステートメントはなく、行も 0 です。現在の CPU 時間は 1 ミリ秒です。 SOQL クエリから 2 行を返し、これらの 2 行を削除した後、Limits.getDMLStatements() によって返される DML ステートメントの総数は 1、Limits.getDMLRows() によって返される行の総数は 2 であり、CPUこのトランザクションの実行に必要な時間は 51 ミリ秒です。
ベスト プラクティスの例: 「ループ内で DML を使用しない」
ガバナー制限を取得せずにコードを実行する方法を見てみましょう。まず、「for」ループ自体で「WorkOrder」サブジェクトを「Product Name」に割り当てることにより、「WorkOrder」オブジェクトから「Product」オブジェクト(API – Product2)にレコードを作成します。次のコードを見てみましょう。
Product2 prod_obj;for (WorkOrder wo_object : [SELECT Subject FROM WorkOrder])
{
prod_obj = 新しい Product2(名前 = wo_object.Subject);
prod_obj を挿入します。
}
リスト (prod_s) を宣言し、prod_obj をリストに格納することにより、これをより適切に行うことができます。このリストをループ外の製品に挿入できます。
ListProduct2 prod_obj;
for (WorkOrder wo_object : [SELECT Subject FROM WorkOrder])
{
prod_obj = 新しい Product2(名前 = wo_object.Subject);
prod_s.add(prod_obj);
}
prod_obj を挿入します。
結論
詳細な説明とともに、Salesforce での Apex の制限について学びました。非同期 Apex プロセスを使用して、同期 Apex と比較してより優れたガバナー制限を取得することをお勧めします。また、さまざまなシナリオのガバナー制限についても学び、「制限」クラスの制限カウントに関するサンプル デモンストレーションを行いました。また、1 つの DML ステートメントを実行して、DML ステートメントの数、行、および CPU 時間を検証しました。ベスト プラクティスの例を 1 つ取り上げて、このガイドを締めくくりました。