Apex-governor-limits

提供:Dev Guides
移動先:案内検索

Apex-ガバナーの制限

ガバナーの実行制限により、Force.comマルチテナントプラットフォーム上のリソースを効率的に使用できます。 これは、効率的な処理のためのコード実行に関してSalesforce.comによって指定された制限です。

ガバナー制限とは何ですか?

知っているように、Apexはマルチテナント環境で実行されます。つまり、単一のリソースがすべての顧客と組織で共有されます。 したがって、誰もリソースを独占しないようにする必要があります。したがって、Salesforce.comは、コード実行を管理および制限する一連の制限を作成しました。 ガバナーの制限のいずれかを超えると、エラーがスローされ、プログラムの実行が停止します。

開発者の観点からは、コードがスケーラブルであり、制限に達していないことを確認することが重要です。

これらの制限はすべて、トランザクションごとに適用されます。 単一のトリガーの実行は1つのトランザクションです。

これまで見てきたように、トリガー設計パターンは制限エラーを回避するのに役立ちます。 他の重要な制限が表示されます。

SOQLクエリ制限の回避

トランザクションごとに発行できるクエリは100のみです。つまり、コードが100を超えるSOQLクエリを発行すると、エラーがスローされます。

この例は、SOQLクエリの制限に到達する方法を示しています-

次のトリガーは、顧客のリストを反復処理し、子レコード(請求書)の説明を文字列「Ok to Pay」で更新します。

//Helper class:Below code needs o be checked.
public class CustomerTriggerHelper {

  public static void isAfterUpdateCall(Trigger.new) {
      createInvoiceRecords(trigger.new);//Method call
      updateCustomerDescription(trigger.new);
   }

  //Method To Create Invoice Records
   public static void createInvoiceRecords (List<apex_customer__c> customerList) {
      for (APEX_Customer__c objCustomer: customerList) {

         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {

           //condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            objInvoice.APEX_Status__c = 'Pending';
            InvoiceList.add(objInvoice);
         }
      }
      insert InvoiceList;//DML to insert the Invoice List in SFDC
   }

  //Method to update the invoice records
   public static updateCustomerDescription (List<apex_customer__c> customerList) {
      for (APEX_Customer__c objCust: customerList) {
         List<apex_customer__c> invList = [SELECT Id, Name,
            APEX_Description__c FROM APEX_Invoice__c WHERE APEX_Customer__c = :objCust.id];

        //This query will fire for the number of records customer list has and will
        //hit the governor limit when records are more than 100
         for (APEX_Invoice__c objInv: invList) {
            objInv.APEX_Description__c = 'OK To Pay';
            update objInv;
           //Update invoice, this will also hit the governor limit for DML if large
           //number(150) of records are there
         }
      }
   }
}

「updateCustomerDescription」メソッドが呼び出され、顧客レコードの数が100を超えると、SOQL制限に達します。 これを回避するには、ForループでSOQLクエリを記述しないでください。 この場合、SOQLクエリはForループで記述されています。

以下は、DMLおよびSOQLの制限を回避する方法を示す例です。 ネストされた関係クエリを使用して請求書レコードを取得し、コンテキスト変数 trigger.newMap を使用してidおよびCustomerレコードのマップを取得しました。

//SOQL-Good Way to Write Query and avoid limit exception
//Helper Class
public class CustomerTriggerHelper {
   public static void isAfterUpdateCall(Trigger.new) {
      createInvoiceRecords(trigger.new); //Method call
      updateCustomerDescription(trigger.new, trigger.newMap);
   }

  //Method To Create Invoice Records
   public static void createInvoiceRecords (List<apex_customer__c> customerList) {
      for (APEX_Customer__c objCustomer: customerList) {

         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {

           //condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            objInvoice.APEX_Status__c = 'Pending';
            InvoiceList.add(objInvoice);
         }
      }
      insert InvoiceList;//DML to insert the Invoice List in SFDC
   }

  //Method to update the invoice records
   public static updateCustomerDescription (List<apex_customer__c>
      customerList, Map<id, apex_customer__c> newMapVariable) {
      List<apex_customer__c> customerListWithInvoice = [SELECT id,
         Name,(SELECT Id, Name, APEX_Description__c FROM APEX_Invoice__r) FROM
         APEX_Customer__c WHERE Id IN :newMapVariable.keySet()];

     //Query will be for only one time and fetches all the records
      List<apex_invoice__c> invoiceToUpdate = new
      List<apex_invoice__c>();

      for (APEX_Customer__c objCust: customerList) {
         for (APEX_Invoice__c objInv: invList) {
            objInv.APEX_Description__c = 'OK To Pay';
            invoiceToUpdate.add(objInv);
           //Add the modified records to List
         }
      }
      update invoiceToUpdate;
   }
}

DML一括呼び出し

この例は、バルクトリガーとトリガーヘルパークラスパターンを示しています。 最初にヘルパークラスを保存してから、トリガーを保存する必要があります。

-以前に作成した「CustomerTriggerHelper」クラスに以下のコードを貼り付けます。

//Helper Class
public class CustomerTriggerHelper {
   public static void isAfterUpdateCall(List<apex_customer__c> customerList,
      Map<id, apex_customer__c> mapIdToCustomers, Map<id, apex_customer__c>
      mapOldItToCustomers) {
      createInvoiceRecords(customerList, mapOldItToCustomers);  //Method call
      updateCustomerDescription(customerList,mapIdToCustomers,
      mapOldItToCustomers);
   }

  //Method To Create Invoice Records
   public static void createInvoiceRecords (List<apex_customer__c>
      customerList, Map<id, apex_customer__c> mapOldItToCustomers) {
      List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>();
      List<apex_customer__c> customerToInvoice = [SELECT id, Name FROM
         APEX_Customer__c LIMIT 1];

      for (APEX_Customer__c objCustomer: customerList) {
         if (objCustomer.APEX_Customer_Status__c == 'Active' &&
            mapOldItToCustomers.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {
           //condition to check the old value and new value
            APEX_Invoice__c objInvoice = new APEX_Invoice__c();
            objInvoice.APEX_Status__c = 'Pending';
            objInvoice.APEX_Customer__c = objCustomer.id;
            InvoiceList.add(objInvoice);
         }
      }
      system.debug('InvoiceList&&&'+InvoiceList);
      insert InvoiceList;
     //DML to insert the Invoice List in SFDC. This also follows the Bulk pattern
   }

  //Method to update the invoice records
   public static void updateCustomerDescription (List<apex_customer__c>
      customerList, Map<id, apex_customer__c> newMapVariable, Map<id,
      apex_customer__c> oldCustomerMap) {
      List<apex_customer__c> customerListWithInvoice = [SELECT id,
      Name,(SELECT Id, Name, APEX_Description__c FROM Invoices__r) FROM
         APEX_Customer__c WHERE Id IN :newMapVariable.keySet()];

     //Query will be for only one time and fetches all the records
      List<apex_invoice__c> invoiceToUpdate = new List<apex_invoice__c>();
      List<apex_invoice__c> invoiceFetched = new List<apex_invoice__c>();
      invoiceFetched = customerListWithInvoice[0].Invoices__r;
      system.debug('invoiceFetched'+invoiceFetched);
      system.debug('customerListWithInvoice****'+customerListWithInvoice);

      for (APEX_Customer__c objCust: customerList) {
         system.debug('objCust.Invoices__r'+objCust.Invoices__r);
         if (objCust.APEX_Active__c == true &&
            oldCustomerMap.get(objCust.id).APEX_Active__c == false) {
            for (APEX_Invoice__c objInv: invoiceFetched) {
               system.debug('I am in For Loop'+objInv);
               objInv.APEX_Description__c = 'OK To Pay';
               invoiceToUpdate.add(objInv);
              //Add the modified records to List
            }
         }
      }
     system.debug('Value of List ***'+invoiceToUpdate);
     update invoiceToUpdate;
     //This statement is Bulk DML which performs the DML on List and avoids
     //the DML Governor limit
   }
}

//Trigger Code for this class: Paste this code in 'Customer_After_Insert'
//trigger on Customer Object
trigger Customer_After_Insert on APEX_Customer__c (after update) {
   CustomerTriggerHelper.isAfterUpdateCall(Trigger.new, trigger.newMap,
      trigger.oldMap);
  //Trigger calls the helper class and does not have any code in Trigger
}

Salesforceガバナーのその他の制限

次の表に、重要なガバナーの制限を示します。

Description Limit
Total heap size 6 MB/12 MB
Total number of DML statements issued 150
Total number of records retrieved by a single SOSL query 2000
Total number of SOSL queries issued 20
Total number of records retrieved by Database.getQueryLocator 10000
Total number of records retrieved by SOQL queries 50000