Apex - Giới hạn quản lý

Các giới hạn thực thi của Thống đốc đảm bảo việc sử dụng tài nguyên hiệu quả trên nền tảng nhiều đối tượng Force.com. Đó là giới hạn do Salesforce.com chỉ định về việc thực thi mã để xử lý hiệu quả.

Giới hạn của Thống đốc là gì?

Như chúng ta đã biết, Apex chạy trong môi trường nhiều người thuê, tức là, một tài nguyên duy nhất được chia sẻ bởi tất cả các khách hàng và tổ chức. Vì vậy, cần phải đảm bảo rằng không ai độc quyền tài nguyên và do đó Salesforce.com đã tạo ra bộ giới hạn chi phối và giới hạn việc thực thi mã. Bất cứ khi nào vượt qua bất kỳ giới hạn thống đốc nào, nó sẽ xuất hiện lỗi và sẽ tạm dừng việc thực thi chương trình.

Từ quan điểm của Nhà phát triển, điều quan trọng là đảm bảo rằng mã của chúng tôi phải có thể mở rộng và không đạt đến giới hạn.

Tất cả các giới hạn này được áp dụng trên cơ sở giao dịch. Một lần thực hiện kích hoạt duy nhất là một giao dịch.

Như chúng ta đã thấy, mẫu thiết kế trình kích hoạt giúp tránh lỗi giới hạn. Bây giờ chúng ta sẽ thấy các giới hạn quan trọng khác.

Tránh giới hạn truy vấn SOQL

Bạn chỉ có thể đưa ra 100 truy vấn cho mỗi giao dịch, nghĩa là khi mã của bạn sẽ đưa ra hơn 100 truy vấn SOQL thì nó sẽ báo lỗi.

Thí dụ

Ví dụ này cho thấy cách đạt đến giới hạn truy vấn SOQL:

Trình kích hoạt sau lặp lại danh sách khách hàng và cập nhật mô tả (Hóa đơn) của bản ghi con với chuỗi '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
         }
      }
   }
}

Khi phương thức 'updateCustomerDescription' được gọi và số lượng bản ghi khách hàng nhiều hơn 100, thì nó sẽ đạt đến giới hạn SOQL. Để tránh điều này, đừng bao giờ viết truy vấn SOQL trong For Loop. Trong trường hợp này, truy vấn SOQL đã được viết trong vòng lặp For.

Sau đây là một ví dụ sẽ chỉ ra cách tránh DML cũng như giới hạn SOQL. Chúng tôi đã sử dụng truy vấn mối quan hệ lồng nhau để tìm nạp các bản ghi hóa đơn và sử dụng biến ngữ cảnhtrigger.newMap để lấy bản đồ id và hồ sơ Khách hàng.

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

Cuộc gọi hàng loạt DML

Ví dụ này cho thấy trình kích hoạt Hàng loạt cùng với mẫu lớp của trình trợ giúp trình kích hoạt. Bạn phải lưu lớp trợ giúp trước và sau đó lưu trình kích hoạt.

Note - Dán mã bên dưới vào lớp 'CustomerTriggerHelper' mà chúng tôi đã tạo trước đó.

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

Các giới hạn khác của Thống đốc Salesforce

Bảng sau liệt kê các giới hạn quan trọng của thống đốc.

Sự miêu tả Giới hạn
Tổng kích thước đống 6 MB / 12 MB
Tổng số câu lệnh DML đã phát hành 150
Tổng số bản ghi được truy xuất bởi một truy vấn SOSL 2000
Tổng số truy vấn SOSL đã phát hành 20
Tổng số bản ghi được truy xuất bởi Database.getQueryLocator 10000
Tổng số bản ghi được truy xuất bởi các truy vấn SOQL 50000