[SalesForce] is it possible to call a single batch job from multiple schedule apex

Hi i would like to know is it possible to have multiple scheduled Apex calling a single Batch Apex? The reason why i have multiple schedule apex is becaus different each 1 excute a different record type

Scheduled APEX 1:

global class schedule_call_apex implements Schedulable{
 global void execute(SchedulableContext sc ){

    static Id sgCtcId = [SELECT Id FROM RecordType WHERE Name = 'SG' AND SobjectType = 'Contact']
    static Id sgCpgId= [SELECT Id FROM RecordType WHERE Name = 'SG' AND SobjectType = 'Campaign']

    Batchjob job = newBatchjob(sgCtcId ,sgCpgId);
    Database.executeBatch(job,200);
 }}

Scheduled APEX 2:

global class schedule_call_apex2 implements Schedulable{
 global void execute(SchedulableContext sc ){

    static Id twCtcId = [SELECT Id FROM RecordType WHERE Name = 'TW' AND SobjectType = 'Contact']
    static Id twCpgId= [SELECT Id FROM RecordType WHERE Name = 'TW' AND SobjectType = 'Campaign']


    Batchjob job = newBatchjob(twCtcId,twCpgId );
    Database.executeBatch(job,200);
 }}

My Batch job:

global class test_batch_job implements Database.Batchable<sObject>{
Integer subtotalUpdCst_actual = 0;
global string ctc_types;
global string cpgn_types;

global test_batch_job(String ctc_type, String cpgn_type){

    this.ctc_types = ctc_type;
    this.cpgn_types = cpgn_type;
}

global Database.QueryLocator start(Database.BatchableContext BC)
{

    String query = 'SELECT Id,Name,YTD_Email_Campaign__c FROM Contact WHERE RecordTypeId = \'' + ctc_types +'\'';

    return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<Contact> scope){
List <Campaign> cmpgn = new List <Campaign>();
List <CampaignMember> cpgn_mb = new List<CampaignMember>();
List<Contact> updateCtcs = new List<Contact>();

cmpgn = [SELECT ID, Campaign_Effective_Start_Date__c, Year__c, Channel__c FROM Campaign WHERE Year__c = '2014' and Channel__c = 'Email' and RecordTypeId =: cpgn_types];
cpgn_mb = [SELECT Id, ContactId From CampaignMember where CampaignId in :cmpgn];

for(Contact ctc : scope){

    System.debug('ctc >'  + ctc);
    Integer emailCampaign = 0;
        for(CampaignMember cmb : cpgn_mb){
            if(cmb.ContactId == ctc.Id){
                emailCampaign += 1;
            }
        }

        if (ctc.YTD_Email_Campaign__c != emailCampaign) {
            ctc.YTD_Email_Campaign__c = emailCampaign;
        }

        updateCtcs.add(ctc);

}
System.debug('updatectcs >>' + updateCtcs);
List<Database.SaveResult> r4 = Database.update(updateCtcs, false);
for( Database.Saveresult r : r4 ){
    if ( r.isSuccess()){
        subtotalUpdCst_actual = subtotalUpdCst_actual + 1;
        System.debug('Database.Saveresult >> ' + r);
    }else{
        for ( Database.Error e : r.getErrors() ){
            System.debug ( updateCtcs + '\n' + e.getStatusCode() + ': ' + e.getMessage());
        } 
    }
}}}

now my worry is that if i schedule both my APEX to be executed at 10pm very night, how will my global variable 'cpgn_types' & 'ctc_types' get instantiated? will it get overwritten? Let say it process my 1st apex (SG) first which contain 50k+ records and i execute it 200/batch so during the process my global variable 'cpgn_types' & 'ctc_types' will be 'SG' until all 50k+ is completed then only proceed to my 2nd APEX (TW) and my global variable 'cpgn_types' & 'ctc_types' will become 'TW'? Or it run concurrently and my global variable 'cpgn_types' & 'ctc_types' change accordingly to which apex calling it?

Best Answer

Direct answer: No, that won't cause you any problems. The execution context will be different each time the batch job is fired.

Something else to keep in mind: You don't need to define your batch job or its methods as global. This was the case when batch jobs first came on the scene, but not anymore. I'd recommend defining them as public instead. (No need to use global if you don't have to!)

Also, ctc_types and cpgn_types don't need to be defined as global. You can set them to private, since they're only being used by methods inside the test_batch_job class. Again, always better to encapsulate when you can.

Related Topic