function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Vladimir BessonovVladimir Bessonov 

DML and Batch limits

Hey
Can someone tell me what are the limits for the code below? or how to estimate it? 
 
/*****************************************************************************
* Description: Class that implements Batch interface and allows to with DML > 10000

*/

    public with sharing class BatchCreateSerializedParts implements Database.Batchable<sObject> {
        String ProjectConfigID;
        String ProjectID;
        Integer VehicleFleetStartNumber;
        ComponentProjectConfiguration__c ProjectConfig;
    
        List<SerializedPartsSet__c> SerPartsSetConfig;
        List<project_Serialized_Parts_Set__c> SerPartsSets = new List<project_Serialized_Parts_Set__c>();
        List<project_Serialized_Part__c> SerParts = new List<project_Serialized_Part__c>();
    
        public BatchCreateSerializedParts(String ProjectConfigID, String ProjectID) {
            this.ProjectConfigID = ProjectConfigID;
            this.ProjectID = ProjectID;
                // not Batch operations 
            ProjectConfig = [Select ID, Name, Vehicle_fleet_start_number__c from ComponentProjectConfiguration__c where ID =: ProjectConfigID];
            VehicleFleetStartNumber = Integer.valueOf(ProjectConfig.Vehicle_fleet_start_number__c);
            SerPartsSetConfig = [Select ID, Name, Quantity__c from SerializedPartsSet__c where Project__c =: ProjectConfigID];

            for (SerializedPartsSet__c partSet : SerPartsSetConfig) {
    
                //   Double Total = part.Number_of_units__c * part.Quantity__c;
                   project_Serialized_Parts_Set__c NewPartSet = New project_Serialized_Parts_Set__c(Name = partSet.Name, Project__c =ProjectID, Quantity__c = partSet.Quantity__c);
                     SerPartsSets.add(NewPartSet);
                   } 
             
            try {insert SerPartsSets;} catch (system.Dmlexception e) { system.debug (e);}

            for(project_Serialized_Parts_Set__c partSet: SerPartsSets){ 
                    // ITERATE PART SETS. PROPULSION & TRUCK    
    
                SerializedPartsSet__c ConfPartSet = [Select ID, Name, Project__c from SerializedPartsSet__c where Project__c =: ProjectConfigID AND Name =: partSet.Name];
                List <SerializedPart__c> SerPartsConfig = [Select ID, Name, Quantity__c, Material_Number__c, Supplier_Part_Number__c, Supplier__c from SerializedPart__c where SerializedPartSet__c =: ConfPartSet.ID];
                    // ITERATE OVER SETS - for example 400
                for(Integer i=0; i<partSet.Quantity__c;i++){
        
                    for(SerializedPart__c part: SerPartsConfig){
        
                
                        if( part.Quantity__c == 1) {
                            system.debug('PART QUANTITY is 1:' + part.Quantity__c ); 
                            
                            project_Serialized_Part__c newPart = new project_Serialized_Part__c(
                            Name= part.Name, Quantity__c = part.Quantity__c , Material_Number__c = part.Material_Number__c, 
                            Set_Number__c = i + VehicleFleetStartNumber, Status__c = 'NOT SENT',
                            Supplier_Part_Number__c = part.Supplier_Part_Number__c, 
                            Supplier__c = part.Supplier__c, Serialized_Part_Set__c = partSet.ID); 
                        
                            SerParts.add(newPart);}
                            else {
                                system.debug('PART QUANTITY is > 1:' + part.Quantity__c );
                                for(Integer j=0; j<part.Quantity__c; j++) {
                                    project_Serialized_Part__c newPart = new project_Serialized_Part__c(
                                    Name= part.Name, Quantity__c = 1 , Material_Number__c = part.Material_Number__c, 
                                    Set_Number__c = i + VehicleFleetStartNumber, Status__c = 'NOT SENT',
                                    Supplier_Part_Number__c = part.Supplier_Part_Number__c, 
                                    Supplier__c = part.Supplier__c, Serialized_Part_Set__c = partSet.ID); 
                                
                                    SerParts.add(newPart);
                                }
                            }
        
                        }
        
                    }
                }         
        }
    
        public Iterable<SObject> start(Database.BatchableContext bc) {
            return SerParts;
        }

        public void execute(Database.BatchableContext bc, List<project_Serialized_Part__c> SerParts) { 
            for(project_Serialized_Part__c p : SerParts){ 
                insert p;
            }
        }
    
        public void finish(Database.BatchableContext bc){
            System.debug('Succesfully inserted Serialized parts and Sets');
        }
    }

and another one
 
/******************************************************************************

* Description: Class that implements Batch interface and allows to with DML > 10000
*/

public with sharing class BatchCreateNonSerializedParts implements Database.Batchable<sObject> {
    String ProjectConfigID;
    String ProjectID;
    Integer VehicleFleetStartNumber;
    ComponentProjectConfiguration__c ProjectConfig;

    List<NonSerializedPart__c> NonSerPartsConfig;
    List<project_Non_Serialized_Part__c> NonSerParts = new List<project_Non_Serialized_Part__c>();
    List<Acceptance__c> NonSerPartAcceptances = new List<Acceptance__c>();  


    public BatchCreateNonSerializedParts(String ProjectConfigID, String ProjectID) {
        this.ProjectConfigID = ProjectConfigID;
        this.ProjectID = ProjectID;

        ProjectConfig = [Select ID, Name, Vehicle_fleet_start_number__c from ComponentProjectConfiguration__c where ID =: ProjectConfigID];
        VehicleFleetStartNumber = Integer.valueOf(ProjectConfig.Vehicle_fleet_start_number__c);

        NonSerPartsConfig = [Select ID, Name, Number_of_units__c, Quantity__c, Unit_of_measurement__c, Material_Number__c, Supplier_Part_Number__c, Supplier__c from NonSerializedPart__c where Project__c =: ProjectConfigID];
        
        for (NonSerializedPart__c part : NonSerPartsConfig) {
        Double Total = part.Number_of_units__c * part.Quantity__c;
        project_Non_Serialized_Part__c NewPart = New project_Non_Serialized_Part__c(Name = part.Name, Project__c =ProjectID,
        Material_Number__c = part.Material_Number__c, Supplier__c = part.Supplier__c, 
        Supplier_Part_Number__c = part.Supplier_Part_Number__c, 
        Total_Quantity__c = Total ,Unit_of_measurement__c = part.Unit_of_measurement__c,
        Number_of_units__c = part.Number_of_units__c, unit_Quantity__c = part.Quantity__c);

        NonSerParts.add(NewPart);
        
        }
        insert NonSerParts;
        for(project_Non_Serialized_Part__c part : NonSerParts){ 
                
            for(Integer i=0;i<part.Number_of_units__c;i++){
                    Acceptance__c newAcceptance = new Acceptance__c(Non_Serialized_Part__c = part.id, Quantity__c = part.unit_Quantity__c,
                    Unit_of_measurement__c = part.Unit_of_measurement__c, Acceptance_Non_Serialized_Part__c = part.Name, Status__c = 'NOT SENT');  
                    NonSerPartAcceptances.add(newAcceptance);
                    System.debug('Acceptances size: ' + NonSerPartAcceptances.size());
                }
        }

    }
    
    public Iterable<SObject> start(Database.BatchableContext bc) {

       return NonSerPartAcceptances;
    }

    public void execute(Database.BatchableContext bc, List<Acceptance__c> NonSerPartAcceptances) {

        for(Acceptance__c a : NonSerPartAcceptances){ 
            insert a;
        }   
    }
    public void finish(Database.BatchableContext bc){
        System.debug('Succesfully inserted Non Serialized parts and Acceptances');
    }
}

​​​​​​​



 
ShivankurShivankur (Salesforce Developers) 
Hi Vladimir,

You could use the debug logs to analyze the limits being used for the apex classes posted.

The limits consumed during transaction looks like below in your debug logs:
LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 0 out of 150
  Number of DML rows: 0 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10
For more reference:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_debugging_debug_log.htm

Hope above information helps. Please mark as Best Answer so that it can help others in future.

Thanks.