when i execute this schedule apex class from developer console
the class is scheduled at 4 different timings as queue.
when "schedule Job2" running i got this exception in debug log shows
"|EXCEPTION_THROWN|[21]|System.AsyncException: The Apex job named
"Scheduled Job0" is already scheduled for execution"
and in debug log the future call shows : "Number of future calls: 1 out of 50"
but i'm not getting the any records pulling from external source
this is scheduled class
global class SchedulingService implements Schedulable {
global void execute(SchedulableContext SC){
ServiceNowUpsert.GetIncident('abcd','1234','https://abcd.service-now.com');
String day = string.valueOf(system.now().day());
String month = string.valueOf(system.now().month());
String hour = string.valueOf(system.now().hour());
String minute = string.valueOf(system.now().minute() + 15);
String second = string.valueOf(system.now().second());
String year = string.valueOf(system.now().year());
String cronStr = '0 0,15 * * * *';//changes required
String strJobName = 'Job-' + second + '_' + minute + '_' + hour + '_' + day + '_' + month + '_' + year;
// String strSchedule = '0 ' + minute + ' ' + hour + ' ' + day + ' ' + month + ' ?' + ' ' + year;
//System.schedule(strJobName, cronStr, new SchedulingServiceNow()); //changes required
System.schedule('Scheduled Job0', '0 0 * * * ?', new SchedulingService ());
System.schedule('Scheduled Job1', '0 15 * * * ?', new SchedulingService ());
System.schedule('Scheduled Job2', '0 30 * * * ?', new SchedulingService ());
System.schedule('Scheduled Job3', '0 45 * * * ?', new SchedulingService ());
for( CronTrigger c:[Select State,Id,EndTime,CronExpression From CronTrigger where
NextFireTime= null AND State='DELETED' Limit 100]){
System.abortJob(c.id);
}
}
}
This is my apex class
global with sharing class ServiceNowUpsert {
@TestVisible static HttpResponse res;
@future(callout=true)
global static void GetIncident(String username1, String password1, String endpointUrl1){
Http http = new Http();
HttpRequest req = new HttpRequest();
Blob headerValue = Blob.valueOf(username1 + ':' + password1);
String authorizationHeader = 'BASIC ' +
EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization', authorizationHeader);
req.setHeader('Content-Type', 'application/json'); //displays data in JSON format
req.setEndpoint(endpointUrl1+'/api/now/table/incident?sysparm_query=sys_updated_onONLast+hour%40javascript%3Ags.hoursAgoStart%282%29%40javascript%3Ags.hoursAgoEnd%280%29&sysparm_fields=impact%2Cincident_state%2Cshort_description%2Csys_id%2Ccontact_type&u_sftype=true');
req.setMethod('GET');
res = http.send(req);
System.debug('MyResult == :'+res.getBody());
Deserialization.ResponseResult theresult1 = (Deserialization.ResponseResult)JSON.deserialize(res.getBody(), Deserialization.ResponseResult.class);
System.debug('MyResult == :' + theresult1 );
List<Case> casesToUpsert = new List<Case>();
for(Deserialization d : theresult1.result ){
Case c = new Case();
c.Priority = d.impact;
c.Status = d.incident_state;
c.Subject = d.short_description;
c.ServiceNowId__c = d.sys_id;
c.Origin = d.contact_type;
casesToUpsert.add(c);
}
system.debug('Cases to UPsert ::: ' +casesToUpsert);
if(casesToUpsert.size()>0){
Database.upsert(casesToUpsert,false) ;
}
}
}
How to work my scheduled class perfectly running for every 15 mins and pulling the records from external source?
Best Answer
Its basically the issue with the scheduled job names. When Scheduled Job2 is running and trying to scheduled next set of Scheduled job its finding that a job named Scheduled Job0 is already running or scheduled. So you should develope a logic to name your scheduled jobs to be unique.
You can use the current timestamp in your scheduled job name like this:
It should make your scheduled job names unique and conflict-less.