7

I have two Apex classes implementing Schedulable and Batchable as follows:

Class implementing Schedulable interface:

public class ScheduleClass implements Schedulable {

    public void execute(SchedulableContext SC) {
        BatchClass obj = new BatchClass();
        Id batchID = database.executebatch(obj);
    }
}

Class implementing Batchable interface:

public class BatchClass implements Database.Batchable<sObject> {

    public BatchClass(){
        //Simplified version of the actual SOQL query.
        List<Sobject> = [SELECT     Id 
                           FROM     ObjectA__c 
                           WHERE    Id
                           IN       (SELECT     ObjectA__c 
                                        FROM    ObjectB__c)];
                                        WHERE   Field1__c = TRUE)
                           AND  Field2__c = TRUE];
    }

    //Ommitted start,execute and finish method for the sake of simplicity.
}

Few important things about the SOQL query inside the BatchClass constructor:

  • Object ObjectB__c has total of 2810941 rows(close to 2.8 million rows).
  • Object ObjectA__c has total of 30004 rows.
  • This is what Query Plan says about the SOQL query:

    enter image description here

Problem Description:

  • I scheduled ScheduleClass from Schedule Apex screen in setup to run every day at specific time.
  • I see there is entry in CronTrigger object and it shows NextFireTime correctly. However, when it runs, it runs up to the SOQL query inside the BatchClass and CronJob status goes to DELETED status.
  • My debug log page shows this:

enter image description here

Why does it show status as success here? Though execution time(duration) is out of bounds by all means.

  • I ran the same query in anonymous apex window and debug log shows that execution took total of 27 minutes (url to the simplified version of anonymous apex debug log : https://pastebin.com/etw9d80f)

Same question here. Why didn't it raise any exception ? I was expecting "Apex CPU limit" or "Non-selective query" or "Query time out" exception.

Why there is no exception raised when SOQL query is taking too long to run?

P.S. I am not looking for ways to improve the performance of the query but I am trying to understand as why it is not running into any exceptions.

8

2,147,483,647 just happens to be 231-1. This happens when the total time can't be determined correctly. I suspect this happens because the system intends to put -1 in the database (a typical "invalid value" placeholder), but the sign bit is stripped out, resulting in the largest possible signed Integer value.

Note that the 10 minute query "rule" is actually more of a "guideline". The system "may" terminate any query that runs longer than 10 minutes. It may also choose not to, if the resources are available. Also, typically speaking, administrators may issue queries that run far longer than normal users do, with the intent that they probably need this data. Again, you'll need to check for the actual Batchable log to see if that was the case. If scheduled as an administrator, it has a slim chance of running normally, but it's certainly not impossible.

It appears you've hit a bug in the system; you're limited to just 50,000 rows of query in a normal transaction, so it sounds like the the scheduled job may actually be aborting abnormally. You'll want to file a bug with Developer Support. Ideally, this code should return a status code that indicates failure.

You'll need to move the query to the start method, instead of the constructor. Optimization or not, your code will likely never work correctly as long as you're trying to query all of the records in the constructor.

  • I missed to mention this but batch job did not run. The schedule job debug log(with finest level) shows that last line executed was the SOQL query inside the batch class constructor. Schedule class did not run this line Database.executeBatch(obj). – javanoob Jan 6 '18 at 4:04
  • Also, why do you think it did not throw Non-Selective query error here? Is it thrown only in trigger context? – javanoob Jan 6 '18 at 4:05
  • Not sure if you are still editing your answer.. record(scheduled job) status is changing to DELETED in CronTrigger object when this is happening and scheduled job is not running anymore. – javanoob Jan 6 '18 at 4:09
  • @javanoob Yeah, I misread some of your code. Putting a query in the constructor likely isn't going to work well; you want to do your main query in the start method instead. I've edited this to be more in line with your actual question. – sfdcfox Jan 6 '18 at 4:13
  • This query is returning only 2147 rows, 50,000 rows limit is still applied? I thought 50,000 rows limit is applied for the number of rows returned. Documentation says "Total number of records retrieved by SOQL queries: 50000" – javanoob Jan 6 '18 at 4:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.