ApexSensei

Drills › Work in the background

Keep counts across Batch transactions

Work in the background · Advanced · 25 min · Runs in your Salesforce Developer org · Apex Path

Scenario. Operations wants a background review plus one summary at the end that says how many Accounts were reviewed and how many were already done.

Add Database.Stateful so counts gathered in execute are still there when finish writes the summary.

What you will learn

start, each execute and finish run in separate transactions. Without Database.Stateful, instance fields go back to their starting values in each one, so a counter you raise in execute reads 0 in finish. Add the interface to keep them:

public class ReviewBatch
    implements Database.Batchable<SObject>, Database.Stateful {

Gotcha. Keep stateful fields small, like counts or Ids. Big lists slow every transaction down.

The task

Make the Batch class stateful so finish can report how many Accounts execute reviewed and how many it skipped.

Examples:

  • 4 Accounts with Description Pending → summary Reviewed: 4, Skipped: 0
  • 2 Pending and 3 already Reviewed → summary Reviewed: 2, Skipped: 3
  • no Accounts → summary Reviewed: 0, Skipped: 0

Requirements:

  1. Add Database.Stateful to the class, so the counters survive between transactions.
  2. In execute, skip each Account whose Description is already Reviewed, and add 1 to skippedCount.
  3. Set every other Account to Reviewed, add 1 to reviewedCount, and update them with one DML statement.
  4. In finish, write Reviewed: <reviewed>, Skipped: <skipped> to the summary Account.

Starter code

public class AS_200B77ADA6CA_StatefulReviewBatch implements Database.Batchable<SObject> {
    private Set<Id> accountIds;
    private Id summaryId;
    private Integer reviewedCount = 0;
    private Integer skippedCount = 0;

    public AS_200B77ADA6CA_StatefulReviewBatch(Set<Id> accountIds, Id summaryId) {
        this.accountIds = accountIds;
        this.summaryId = summaryId;
    }

    public Database.QueryLocator start(Database.BatchableContext context) {
        return Database.getQueryLocator([
            SELECT Id, Description
            FROM Account
            WHERE Id IN :accountIds
        ]);
    }

    public void execute(Database.BatchableContext context, List<SObject> scope) {
    }

    public void finish(Database.BatchableContext context) {
    }
}

When it passes

The checks run the real job with `Database.executeBatch`. Pending Accounts become `Reviewed`, other Accounts stay the same, and the summary shows the counts that `execute` gathered, which only works with `Database.Stateful`.

Try this drill free

You write the Apex yourself. ApexSensei runs it and tells you what passed and what did not.

‹ Build a Batch lifecycle · Schedule an Account review ›