1

My scenario is We have three custom fields in Account object - Closings, LoanAmt, Ranking. Ranking has to be ranked according to Closings amount. When Closings amount is same for couple of accounts, then we have to consider LoanAmt and rank it. I wrote a simple batch class to update Rank. I have inserted 300 records with testdata and executed the batch class with scope as 100. Ranking is happening for every 100 records. so i am getting three records with rank 1 and so on. below is code and please let me know where i went wrong.

global class AccountJVClosingRank_Batch implements Database.Batchable<SObject>, Database.Stateful {
    
    public Integer ranking = 0;
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator([
            SELECT Id, Name, LoanAmt__c, Closings__c
            FROM Account
            WHERE Record_Type_Name__c = 'JV Partner'
            ORDER BY Closings__c DESC, LoanAmt__c DESC NULLS LAST
        ]);
    }

    global void execute(Database.BatchableContext BC, List<Account> scope) {
        Integer i = 1;

        for(Account ac: scope) {
            ac.ClosingRank__c = i;
            i = i + 1;
        }
        update scope;
    }

    global void finish(Database.BatchableContext BC) {
        // Any post execute operations can be done in finish method 
    }
}

1 Answer 1

3

The execute() method is being called once for each batch in your job.

Since you're always resetting Integer i = 1; in execute(), each batch starts with a ranking of 1 (as you've observed). You need a way to persist the "state" of your ranking between batches.

Each call of execute() is a separate transaction, so a static variable won't work.

You could

  • use an SObject record to store the state (and you'd query that in each call of execute())
  • add Database.Stateful to your batch class's implements declaration (e.g. public class MyBatch implements Database.Batchable<SObject>, Database.Stateful) to make class variables persist between batches (but I hear this slows down batch processing)
  • use the org cache (not sure if the session cache would work) to store/retrieve the state, though it's not guaranteed to keep the data in the cache so this is probably a poor choice

The easiest approach would be to use Database.Stateful and use your existing ranking instance variable instead of Integer i within your execute() method.

1
  • Thanks Derek, its working now
    – surya
    Commented Jun 17 at 13:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .