- Apex 编程教程
- 顶点 - 主页
- Apex - 概述
- 顶点 - 环境
- 顶点 - 示例
- Apex - 数据类型
- Apex - 变量
- Apex - 弦乐
- Apex - 数组
- Apex - 常量
- Apex - 决策
- 顶点 - 循环
- Apex - 集合
- Apex - 课程
- Apex - 方法
- Apex - 对象
- Apex - 接口
- Apex-DML
- Apex - 数据库方法
- 顶点 - SOSL
- 顶点-SOQL
- 顶点 - 安全
- Apex - 调用
- Apex - 触发器
- Apex - 触发器设计模式
- Apex - 调节器限制
- Apex - 批处理
- Apex - 调试
- Apex - 测试
- Apex - 部署
- Apex 有用资源
- Apex - 快速指南
- Apex - 资源
- Apex - 讨论
Apex - 调节器限制
调控器执行限制可确保 Force.com 多租户平台上资源的有效利用。这是 Salesforce.com 为高效处理而指定的代码执行限制。
什么是州长限制?
众所周知,Apex运行在多租户环境中,即单一资源由所有客户和组织共享。因此,有必要确保没有人垄断资源,因此 Salesforce.com 创建了一组管理和限制代码执行的限制。每当超过任何调节器限制时,它都会抛出错误并停止程序的执行。
从开发人员的角度来看,确保我们的代码应该可扩展并且不应该达到限制非常重要。
所有这些限制均适用于每笔交易。单个触发器执行就是一个事务。
正如我们所看到的,触发器设计模式有助于避免极限错误。我们现在将看到其他重要的限制。
避免 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 调控器限制
下表列出了重要的调速器限制。
描述 | 限制 |
---|---|
总堆大小 | 6MB/12MB |
发出的 DML 语句总数 | 150 |
单个 SOSL 查询检索的记录总数 | 2000年 |
发出的 SOSL 查询总数 | 20 |
Database.getQueryLocator 检索的记录总数 | 10000 |
SOQL 查询检索的记录总数 | 50000 |