2

Prelude

I understand the following regarding batch Apex:

State Variable Values
stateful static are reset for each batch execute() run
instance (non-static) are maintained across all batch execute() runs
non-stateful static are reset for each batch execute() run
instance (non-static) are reset for each batch execute() run

As I understand it, each batch execute() run is considered a separate transaction.

Background

In an inherited org, I just ran across a non-stateful batch class, which within the execute() method references a static variable in a separate non-Batchable class.

Simplified Example

Separate Class

public class SeparateClass {
    public static Set<Id> staticSetIds = new Set<Id>();
}

Batch Class

public class NonStatefulBatch implements Database.Batchable<sObject> {
    public Database.QueryLocator start(Database.BatchableContext BC) {
        // build query
        return Database.getQueryLocator(query);
    }

    public void execute(Database.BatchableContext BC, List<Account> scope) {
        // Work
        for (Account acc : scope) {
            if (!SeparateClass.staticSetIds.contains(acc.Id) {
            // More work
            SeparateClass.staticSetIds.add(acc.Id);
        }
        // Even more work
    }

    public void finish(Database.BatchableContext BC) {
        System.debug('Finished');
    }
}

Comments

This separate class' static variable is also used in other contexts, such as triggers, where -- if I understand correctly -- it will do what I think they want it to do as all "batches" of a trigger run are considered the same transaction: This variable will maintain value for the full run of the trigger.

I think the original code writer was expecting/hoping that the same thing would happen in this batch class.

Questions

  1. Is my assumption that each batch execute() run is a separate transaction, thus this separate class' static variable value will not be maintained for the full run of the batches?
  2. Would it act differently if this batch class were Stateful?

UPDATE 1

Minutes after posting the original question

I posted this too soon, maybe. After further analysis I see that the batch updates Accounts, and the SeparateClass.staticSetIds is referenced in the before update of the Account trigger handler. I haven't looked at the 1s and 0s yet, but maybe that is why it is used in this batch.

2
  • 1
    1.Yes. 2. No - as long as SeparateClass is not referenced by the object graph tied to any instance variable. One possible solution: based on the state of your (stateful) Batchable. you construct the SeparateClass and initialize it with whatever state it needs. Another solution: have the state in your Batchable include SeparateClass (via an instance variable) and update it as needed throughout the runs. While this solution might appear cleaner, serialization issues could bite.
    – identigral
    Commented Feb 23 at 18:49
  • 1
    Where a static is declared has (almost) zero bearing on its lifecycle. They are always scoped to a transaction, being initialized on first reference within the transaction (this being the only thing it influences - no reference in the txn, then never set). Perhaps they use it to influence processing where this static is used elsewhere. If, say, this batch also performs DML on Account and the static is used somewhere in the Account trigger handling then that trigger handling would be influenced by this static since the DML would be part of the same transaction as the batch execute.
    – Phil W
    Commented Feb 24 at 7:50

0

You must log in to answer this question.

Browse other questions tagged .