Apex - Governer Limits調(diào)節(jié)器限制

2019-10-26 16:26 更新

控制器執(zhí)行限制確保在Force.com多租戶平臺(tái)上有效地使用資源。 它是由Salesforce.com指定的對(duì)代碼執(zhí)行有效處理的限制。


什么是調(diào)節(jié)器限制?

我們知道,Apex在多租戶環(huán)境中運(yùn)行; 即單個(gè)資源由所有客戶和組織共享。 因此,有必要確保沒(méi)有人壟斷資源,因此Salesforce.com已經(jīng)創(chuàng)建了一組管理和限制代碼執(zhí)行的限制。 每當(dāng)任何一個(gè)調(diào)節(jié)器限制被越過(guò),它將拋出錯(cuò)誤,并將停止程序的執(zhí)行。


從開(kāi)發(fā)人員的角度來(lái)看,確保我們的代碼是可擴(kuò)展的并且不應(yīng)該達(dá)到極限是至關(guān)重要的。所有這些限制都適用于每個(gè)交易。 單個(gè)觸發(fā)器執(zhí)行一個(gè)事務(wù)。


正如我們所看到的,觸發(fā)器設(shè)計(jì)模式是一種避免極限誤差的方法。 讓我們看看一些重要的限制。


避免SOQL查詢限制

每個(gè)事務(wù)只能發(fā)出100個(gè)查詢,也就是說(shuō),當(dāng)代碼發(fā)出超過(guò)100個(gè)SOQL查詢時(shí),它會(huì)拋出錯(cuò)誤。


例如:

以下是顯示如何達(dá)到SOQL查詢限制的示例:

以下觸發(fā)器遍歷客戶列表,并使用字符串“Ok to Pay”更新子記錄(發(fā)票)描述。

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

當(dāng)方法'updateCustomerDescription'被調(diào)用,并且客戶記錄的數(shù)量大于100時(shí),它將達(dá)到SOQL限制。


為了避免這種情況,不要在For循環(huán)中寫(xiě)入SOQL查詢。 在這種情況下,SOQL查詢已經(jīng)寫(xiě)入for循環(huán)。


下面是我們可以避免DML以及SOQL限制的示例。 我們使用嵌套關(guān)系查詢來(lái)獲取發(fā)票記錄,并使用上下文變量trigger.newMap來(lái)獲取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批量調(diào)用

正如我們?cè)谠S多示例中看到的,我們一直在列表中添加修改的記錄,然后對(duì)該列表執(zhí)行DML操作,而不是對(duì)單個(gè)記錄執(zhí)行DML。 下面是同樣的例子。 這是批量觸發(fā)器以及觸發(fā)器幫助器類模式的示例。 您必須先保存幫助程序類,然后保存觸發(fā)器。


注意:將以下代碼粘貼到我們之前創(chuàng)建的“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 Governor限制

以下是一些重要的Salesforce Governor限制,我們需要記住。 你可以檢查其他Salesforce Governor限制以及使用Salesdorce.com Apex開(kāi)發(fā)人員指南。

描述限制
Total heap size
總堆大小
6 MB / 12 MB
Total number of DML statements issued
發(fā)出的DML語(yǔ)句的總數(shù)
150
Total number of records retrieved by a single SOSL query
單個(gè)SOSL查詢檢索的記錄總數(shù)
2000
Total number of SOSL queries issued
發(fā)出的SOSL查詢的總數(shù)
20
Total number of records retrieved by Database.getQueryLocator
Database.getQueryLocator檢索的記錄總數(shù)
10000
Total number of records retrieved by SOQL queries
通過(guò)SOQL查詢檢索的記錄總數(shù)
50000

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)