0

i write a Batch apex.i write an execute method .which is using a static variable of another class.because it is shhared.any one can use it and change it.

public void execute(Database.BatchableContext BC, List<sObject> scope){
     x=GMirror.x;

     ...........
     ...........
         .........
y =GMirror.x; 

}

i want to know each batch of 5 in my case will run in transaction or means at this time only this method is running nothing else or in other words i want to know if using another class's method execution in between time first statement execute x=GMirror.x;

and second statement y =GMirror.x;

its possible by another parallel execution of another class's method that these value of GMirror.x get changed ?? these execution this necessary that no one changed value of GMirror.x or value of GMirror.x can be changed by another parallel execution.Please clarify .

1
  • Can I recommend that you review the title of your question, I think something like 'Explain Static Variable sharing in Batch Apex?', it will get more hits and also future users of this site will find your question and the answers more easily. Thanks. :-) Sep 30, 2013 at 8:05

2 Answers 2

1

In context of batch the state of static variable will remain maintained according to assignments by statements executing between execute method and no other parallal executing batch or class which is not part of that context will not impact on state of static variable. But on each transaction it will reset the variable to its default state.

A stateful batch will be helpful if you maintain the static variable value from instance variable in batch class. A no-state batch resets all value in transactions.

In batch gmirror.x and gmirror.y will remain same if no statement changing its value in the context and will become default in next transaction if changed.

1

As per the Salesforce documentation here...

Each execution of a batch Apex job is considered a discrete transaction. For example, a batch Apex job that contains 1,000 records and is executed without the optional scope parameter is considered five transactions of 200 records each.

You can modify this behaviour by applying the interface Database.Statefull to your Apex class.

global class SummarizeAccountTotal implements 
    Database.Batchable<sObject>, Database.Stateful{

In this case the following then applies.

If you specify Database.Stateful in the class definition, you can maintain state across these transactions. When using Database.Stateful, only instance member variables retain their values between transactions. Static member variables don’t and are reset between transactions. Maintaining state is useful for counting or summarizing records as they're processed.

Note that the GMirror.X and GMirror.Y variables need to be 'instance' variables of your class to be stored, otherwise they will be reset. To work around this you could change them to instance variables and store an instance of GMirror in your Apex Class.

public MyJob implements Database.Batchable<sObject>, Database.Stateful 
{
    private GMirror gm = new GMirror();

    public void execute(Database.BatchableContext BC, List<sObject> scope)
    {
        // Here gm.X and gm.Y will be maintain throughout the job
    }
}

Or store X and Y as instance variables in your batch and at the top of your execute method assign them.

public MyJob implements Database.Batchable<sObject>, Database.Stateful 
{
    private Integer gmX;
    private Integer gmY;

    public void execute(Database.BatchableContext BC, List<sObject> scope)
    {
        // Here gmX and gmY will be maintain throughout the job
        GMirror.X = gmX;
        GMirror.Y = gmY;
    }
}

The later option does not require any change to the GMirror class and also does not give rise to potential side effects of persisting other instance variables of this class. For more information see the larger example and explaination in the Salesforce docs here.

More Advanced Thought: As a more advanced option you might want to consider a factory pattern to maintain a static instance of GMirror, but create a GMirror.State inner class that can be passed (perhaps optionally) to the GMirror factory method.

You must log in to answer this question.

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