📅  最后修改于: 2020-11-05 03:19:43             🧑  作者: Mango
调控器执行限制可确保Force.com多租户平台上资源的有效利用。这是Salesforce.com为有效执行代码而指定的限制。
众所周知,Apex在多租户环境中运行,即,所有客户和组织都共享一个资源。因此,有必要确保没有人垄断资源,因此Salesforce.com已创建了一组限制来控制和限制代码执行。每当超过任何调速器限制时,都将引发错误并中止程序的执行。
从开发人员的角度来看,重要的是要确保我们的代码应具有可伸缩性且不会超出限制。
所有这些限制均基于每个交易应用。一个触发器执行就是一个事务。
如我们所见,触发器设计模式有助于避免极限误差。现在,我们将看到其他重要限制。
每个事务只能发出100个查询,也就是说,当代码将发出100个以上的SOQL查询时,它将引发错误。
这个例子展示了如何达到SOQL查询限制-
以下触发器循环访问客户列表,并使用字符串“确定付款”更新子记录的(发票)描述。
// 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 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 customerList) {
for (APEX_Customer__c objCust: customerList) {
List 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和客户记录的映射。
// 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 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
customerList, Map newMapVariable) {
List 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 invoiceToUpdate = new
List();
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;
}
}
此示例显示了批量触发器以及触发器助手类模式。您必须先保存助手类,然后再保存触发器。
注意-将以下代码粘贴到我们之前创建的’CustomerTriggerHelper’类中。
// Helper Class
public class CustomerTriggerHelper {
public static void isAfterUpdateCall(List customerList,
Map mapIdToCustomers, Map
mapOldItToCustomers) {
createInvoiceRecords(customerList, mapOldItToCustomers); //Method call
updateCustomerDescription(customerList,mapIdToCustomers,
mapOldItToCustomers);
}
// Method To Create Invoice Records
public static void createInvoiceRecords (List
customerList, Map mapOldItToCustomers) {
List InvoiceList = new List();
List 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
customerList, Map newMapVariable, Map oldCustomerMap) {
List 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 invoiceToUpdate = new List();
List invoiceFetched = new List();
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
}
下表列出了重要的调速器极限。
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 |