Apex - Governer Limitleri

Vali yürütme sınırları, Force.com çok kiracılı platformundaki kaynakların verimli kullanılmasını sağlar. Verimli işleme için Salesforce.com tarafından kod çalıştırmada belirtilen sınırdır.

Vali Limitleri nelerdir?

Bildiğimiz gibi, Apex çok kiracılı bir ortamda çalışıyor, yani tek bir kaynak tüm müşteriler ve kuruluşlar tarafından paylaşılıyor. Bu nedenle, hiç kimsenin kaynakları tekeline almadığından ve bu nedenle Salesforce.com'un kod yürütmeyi yöneten ve sınırlayan bir dizi sınır oluşturduğundan emin olmak gerekir. Düzenleyici sınırlarından herhangi biri aşıldığında, hata verir ve programın yürütülmesini durdurur.

Bir Geliştiricinin bakış açısından, kodumuzun ölçeklenebilir olması ve sınırları aşmaması gerektiğinden emin olmak önemlidir.

Tüm bu limitler işlem bazında uygulanır. Tek bir tetikleme yürütme, bir işlemdir.

Gördüğümüz gibi, tetik tasarım modeli, limit hatasını önlemeye yardımcı olur. Şimdi diğer önemli sınırları göreceğiz.

SOQL Sorgu Sınırını Önleme

İşlem başına yalnızca 100 sorgu yayınlayabilirsiniz, yani kodunuz 100'den fazla SOQL sorgusu yayınladığında hata verir.

Misal

Bu örnek, SOQL sorgu sınırına nasıl ulaşılabileceğini gösterir -

Aşağıdaki tetikleyici, bir müşteri listesi üzerinde yinelenir ve alt kaydın (Fatura) açıklamasını 'Ödeme Tamam' dizesiyle günceller.

// 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' yöntemi çağrıldığında ve müşteri kayıtlarının sayısı 100'den fazla olduğunda, SOQL sınırına ulaşacaktır. Bundan kaçınmak için, SOQL sorgusunu asla For Loop'a yazmayın. Bu durumda, SOQL sorgusu For döngüsüne yazılmıştır.

Aşağıda, DML'den ve SOQL sınırından nasıl kaçınılacağını gösteren bir örnek verilmiştir. Fatura kayıtlarını almak için iç içe geçmiş ilişki sorgusunu kullandık ve bağlam değişkenini kullandıktrigger.newMap Kimlik haritasını ve Müşteri kayıtlarını almak için.

// 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 Toplu Aramalar

Bu örnek, Toplu tetikleyiciyi tetikleyici yardımcı sınıf modeliyle birlikte gösterir. Önce yardımcı sınıfı kaydetmeniz ve ardından tetikleyiciyi kaydetmeniz gerekir.

Note - Aşağıdaki kodu daha önce oluşturduğumuz 'CustomerTriggerHelper' sınıfına yapıştırın.

// 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
}

Diğer Salesforce Governor Limitleri

Aşağıdaki tablo önemli düzenleyici limitlerini listelemektedir.

Açıklama Sınırı
Toplam yığın boyutu 6 MB / 12 MB
Yayınlanan toplam DML beyanı sayısı 150
Tek bir SOSL sorgusu tarafından alınan toplam kayıt sayısı 2000
Yayınlanan toplam SOSL sorgusu sayısı 20
Database.getQueryLocator tarafından alınan toplam kayıt sayısı 10000
SOQL sorguları tarafından alınan toplam kayıt sayısı 50000