Skip to main content

How to control two batch job execution ?

We are all familiar with batch class in SFDC. This  post is all about to discuss a known issue in batch class and what is workaround for that?

As we know batch class is is required when we are dealing with large number of records and total number of batch job will be decided based on scope parameter (defined while calling a batch class) and total number of records.
Say total number of records = 100
Scope parameter = 5.  Database.executeBatch(new batchclass(),5);
Then batch job will be 20 which means each job will process 5 records.

We can see how many jobs are pending and how many jobs completed in set up-->apex jobs.

While one batch is in progress we invoke same batch class another time having batch size 5 and total number of records 50. Ideally number jobs should be 10 but actually it will be 10 + number of progressing job of previous batch. Which causes data redundancy that means same records will be processed two times in both the batch.This is the known issue in batch class.

The prime motto is two batch should not pic same records.

Let me share the issue what i had come across. External system were passing all the data to SFDC (SFDC had exposed a service to receive data from) then i was storing in staging table(temporary obj) then i was calling batch class after data is inserted in staging table to push into original object.I was calling batch class from a trigger.let say batch size is 5 and 20 records inserted in staging obj then obviously batch will be invoked and 4 jobs will be progress. While third batch job is running another 30 set of records inserted in staging obj then again batch will be invoked and total number jobs will be 30/5=6+ two jobs of previous batch  = 8 jobs will be in progress.That means 2jobs= 10 records will be processed two times.In our original object 50 records should be created but actually total number if records will be 55. 5 duplicate records which is an issue.

Solution :-

  •  Create a flag(check box field) in staging obj. When original records will be created set that flag is true so that after one week these records will be deleted from staging obj.
  • Create a class where check whether batch is in progress or not if not call batch class
  • Scheduler same class every one minute interval until all the progress batch job is completed and check if there is few records to be processed in staging obj.
  • Call same class from trigger if same class is not scheduled.
Technical Details:-
String batchClassId = '01pS0000000Fm2W';
String  schedulerclassId = '01pS0000000FvKF';

global class Scheduling_Svc_WS_CreateBatch implements Schedulable{    // Execute method     global void execute(SchedulableContext SC) {     // Code to be executed when the schedule class wakes up           // code           list<BRASS_Case__c > listOfBrassCases;           list<AsyncApexJob> jobList;           try{                jobList = [select id,ApexClassID,JobType,Status from AsyncApexJob where ApexClassID =:batchClassId AND Status ='Processing'];                listOfBrassCases  = [select id from BRASS_Case__c where Is_Org_Case_Created__c !=true];                          if(jobList.size()==0){             //String cronID = System.scheduleBatch(new Svc_WS_CreateCaseBatch(), 'original case creation', 5);             Database.executebatch(new Svc_WS_CreateCaseBatch(),5);                        }           }catch(QueryException ex){             system.debug('pringint exception---'+ex);           }            // This section of code will schedule the next execution 1 minutes from now     if(listOfBrassCases.size()>0 && (!(jobList.size()>0) || jobList.size()>0)){       datetime nextScheduleTime = system.now().addMinutes(1);         string minute = string.valueof(nextScheduleTime.minute());         string second = string.valueof(nextScheduleTime.second ());         string cronvalue = second+' '+minute+' 0-23 * * ?' ;         string jobName = 'selfReschedulingClass ' +nextScheduleTime.format('hh:mm');           Scheduling_Svc_WS_CreateBatch p = new Scheduling_Svc_WS_CreateBatch();       system.schedule(jobName, cronvalue , p);       system.abortJob(sc.getTriggerId());               }     else{       // this section of code will abort the current schedule job       system.abortJob(sc.getTriggerId());       }              }  }

From Trigger you call above class like this
try{
                list<AsyncApexJob> jobList = [select id,ApexClassID,JobType,Status from AsyncApexJob where ApexClassID =cAND Status ='Queued'];
                if(!(jobList !=null && jobList.size()>0)){
                    datetime nextScheduleTime = system.now().addMinutes(1);
                    string minute = string.valueof(nextScheduleTime.minute());
                    string second = string.valueof(nextScheduleTime.second ());
                    string cronvalue = second+' '+minute+' 0-23 * * ?' ;
                    string jobName = 'selfReschedulingClass ' +nextScheduleTime.format('hh:mm');
                 
                    Scheduling_Svc_WS_CreateBatch p = new Scheduling_Svc_WS_CreateBatch();
                    system.schedule(jobName, cronvalue , p);
                }
                
     
           }catch(Exception ex){
           }


Comments

Popular posts from this blog

Style in LWC

 Following are the ways we can apply in CSS in LWC. 1. Inline CCS Inline CSS is not recommended approaches, it is take highest priority among all CSS. style="color:green;font-size:10px;" is inline CSS added to div < template >     < lightning-card title = "Inline CSS" >         < div >             < div style = "color:green;font-size:10px;" > This is inline Style div </ div >         </ div >     </ lightning-card > </ template >  2. External CSS style can be applied to an elements such as h1, p,div span etc. It can applied to class using "." notation. for example .user{} It can also be applied to pseudo class.  for example .user:hover{} Id locator is not being used in LWC to apply style To apply external css, need to create separate CSS file, file name should be exactly matched with component name. for example - If component name is ...

How to Create/Delete file attachments(Content Document) through Apex ?

 There are 3 standard salesforce objects to store file attachments. Content Document, ContentDocumentVersion, ContentDocumentLink.  Here is the article to talk about these objects and relationship.  https://www.forcetalks.com/blog/contentdocument-and-contentversion-in-salesforce-an-overview/ ContentDocumentVersion ContentDocumentLink This post is all about how to create/delete content document though Apex. Here is code snippet // Insert Content Version record ContentVersion contentVersionRec = new ContentVersion(Title='filename',PathOnClient ='FileName.pdf',VersionData = bodyBlob,origin = 'H'); INSERT contentVersionRec; // this will insert one record in ContentDocument and ContentVersion , ContentDocument  is parent and  ContentVersion is child record // get contentdocument id contentVersionRec = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE Id = :contentVersionRec .Id LIMIT 1]; // Create Content Document Link record- This will attach ...

Lifecycle hooks in LWC

There are 3 phase of LWC component  1. Mounting  A. constructor, B. connnectedCallback C. render D. renderedCallback 2. UnMounting  A. disconnectedcallback 3. Error  A.errorcallback Note - render is not lifecycle hook, it is protected method of Lightning element class. Mounting Phase LWC Creation and Render Life cycle Constructor Method ·        This method called when component is instantiated and It flows from parent to child component. ·        Need to call Super() inside constructor method ·        Can’t access any component properties or child component because it’s not ready yet. ·        Host element can be accessed through “this. template” inside constructor method. ·        Don’t add any attributes to host inside constructor C   constructor (){          super (); //...