- Apex - Deployment
- Apex - Testing
- Apex - Debugging
- Apex - Batch Processing
- Apex - Governer Limits
- Apex - Trigger Design Patterns
- Apex - Triggers
- Apex - Invoking
- Apex - Security
- Apex - SOQL
- Apex - SOSL
- Apex - Database Methods
- Apex - DML
- Apex - Interfaces
- Apex - Objects
- Apex - Methods
- Apex - Classes
- Apex - Collections
- Apex - Loops
- Apex - Decision Making
- Apex - Constants
- Apex - Arrays
- Apex - Strings
- Apex - Variables
- Apex - Data Types
- Apex - Example
- Apex - Environment
- Apex - Overview
- Apex - Home
Apex Useful Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Apex - Governer Limits
Governor execution pmits ensure the efficient use of resources on the Force.com multitenant platform. It is the pmit specified by the Salesforce.com on code execution for efficient processing.
What are Governor Limits?
As we know, Apex runs in multi-tenant environment, i.e., a single resource is shared by all the customers and organizations. So, it is necessary to make sure that no one monopopzes the resources and hence Salesforce.com has created the set of pmits which governs and pmits the code execution. Whenever any of the governor pmits are crossed, it will throw error and will halt the execution of program.
From a Developer s perspective, it is important to ensure that our code should be scalable and should not hit the pmits.
All these pmits are appped on per transaction basis. A single trigger execution is one transaction.
As we have seen, the trigger design pattern helps avoid the pmit error. We will now see other important pmits.
Avoiding SOQL Query Limit
You can issue only 100 queries per transaction, that is, when your code will issue more than 100 SOQL queries then it will throw error.
Example
This example shows how SOQL query pmit can be reached −
The following trigger iterates over a pst of customers and updates the child record s (Invoice) description with string Ok to Pay .
// Helper class:Below code needs o be checked. pubpc class CustomerTriggerHelper { pubpc static void isAfterUpdateCall(Trigger.new) { createInvoiceRecords(trigger.new);//Method call updateCustomerDescription(trigger.new); } // Method To Create Invoice Records pubpc 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 pubpc 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 pst has and will // hit the governor pmit 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 pmit for DML if large // number(150) of records are there } } } }
When the updateCustomerDescription method is called and the number of customer records are more than 100, then it will hit the SOQL pmit. To avoid this, never write the SOQL query in the For Loop. In this case, the SOQL query has been written in the For loop.
Following is an example which will show how to avoid the DML as well as the SOQL pmit. We have used the nested relationship query to fetch the invoice records and used the context variable trigger.newMap to get the map of id and Customer records.
// SOQL-Good Way to Write Query and avoid pmit exception // Helper Class pubpc class CustomerTriggerHelper { pubpc static void isAfterUpdateCall(Trigger.new) { createInvoiceRecords(trigger.new); //Method call updateCustomerDescription(trigger.new, trigger.newMap); } // Method To Create Invoice Records pubpc 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 pubpc 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 Bulk Calls
This example shows the Bulk trigger along with the trigger helper class pattern. You must save the helper class first and then save the trigger.
Note − Paste the below code in CustomerTriggerHelper class which we have created earper.
// Helper Class pubpc class CustomerTriggerHelper { pubpc 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 pubpc 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 pubpc 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 pmit } } // 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 }
Other Salesforce Governor Limits
Following table psts down the important governor pmits.
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 |