[SalesForce] Batch job works when run through Database.executeBatch(), but doesn’t when scheduled

This one is a bit odd and I'm hoping it's something someone has seen before. I wrote a batch class that implements both Batchable and Schedulable. I found that I was writing schedulable classes for the sole purpose of scheduling a batch job so why not write a class that implements both and cut out the excess overhead.

I have the job scheduled to run every 15 minutes. So I set up 4 scheduled jobs like so

System.schedule('Entitlements Calculation 00', '0 0 * * * ?', new EntitlementTotalsBatchJob());
System.schedule('Entitlements Calculation 15', '0 15 * * * ?', new EntitlementTotalsBatchJob());
System.schedule('Entitlements Calculation 30', '0 30 * * * ?', new EntitlementTotalsBatchJob());
System.schedule('Entitlements Calculation 45', '0 45 * * * ?', new EntitlementTotalsBatchJob());

It seemed to work fine at first. Meaning when I first scheduled the job, it worked to make the desired changes to historical records.

What I have been finding lately, is that records that should be updated by my batch class, are not being updated. So for simplification purposes, let's assume my batch class simply takes any account that has a certain checkbox checked, and appends '-Checked' to the end of the account name. (I know this is a ridiculous use case, but it's just for explanatory purposes).

So when I first scheduled the jobs, all the accounts that had that box checked, the names indeed had '-Checked' appended. What I found is that moving forward, accounts that were changed to have the box checked, the names were not changing. The batch job is still running, no errors, but no changes to the records.

Here is where it gets weird. If I simply use an Apex Anonymous window and run

Database.ExecuteBatch(new EntitlementTotalsBatchJob(), 100);

The job runs, and the accounts actually update. So I thought it might be an issue with the scheduling of the job. So I scheduled a manual one-time run of the job like below

System.schedule('Entitlements Calculation NOW', '0 06 09 11 03 ? 2015', new EntitlementTotalsBatchJob());

This scheduled the job for a one-time run 3 minutes from when I scheduled it. That caused the accounts to change as well.

So I am completely confused as to why it would work when manually forced,m but when it has been scheduled to run at regular intervals, it's not working in the same manner.

Has anyone seen this before??

Since the job itself seems to work to perform the logic I want, I thought it would be overkill to post the entire code here as its a large class. Here is the basic stricture of the class though

public class EntitlementTotalsBatchJob implements Database.Batchable<SObject>, Schedulable { 

     public final string query;

     public EntitlementTotalsBatchJob() {

          list<Id> accountIDs = EntitlementTotalsBatchUtility.getAccountIDs();

          String idSet = '\'';
          idSet += String.join(accountIDs,'\',\'');
          idSet += '\'';

          query = 'Select Id, Name, OneSign_Support_Level__c, Cortext_Support_Level__c, OneSign_Support_Expiration__c, Cortext_Subscription_End_Date__c, '
          + 'Active_OneSign_Customer__c, OneSign_Customer_Start_Date__c, '
          + 'Active_Cortext_Customer__c, Cortext_Customer_Start_Date__c, '
          + 'Active_Confirm_Id_Customer__c, Confirm_Id_Customer_Start_Date__c, Confirm_Id_Support_Level__c, Confirm_Id_Subscription_End_Date__c '
          + 'From Account Where Id IN (' + idSet + ')';  
     }

     public void execute(SchedulableContext sc) {
          Database.executeBatch(this, 100);
     }

     public Database.QueryLocator start(Database.BatchableContext bc) {
          return Database.getQueryLocator(query);
     }

     public void execute(Database.BatchableContext bc, List<sObject> scope) {
          //Lots of Amazing Logic and Code
     }

     public void finish(Database.BatchableContext bc) {

    }
}

Has anyone seen this type of behavior before?

Best Answer

My only suggestion would be to try changing the line:

public void execute(SchedulableContext sc) { 
  Database.executeBatch(this, 100); 
} 

to

public void execute(SchedulableContext sc) { 
  Database.executeBatch(new EntitlementTotalsBatchJob(), 100); 
}

I'm just wondering if when the schedule is created there is some kind of caching going on that's causing a strange result when using this. It's a long-shot but maybe worth trying?

Related Topic