function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Amit "CLS"  RangariAmit "CLS" Rangari 

Apex Batch Job with Database.Stateful

Hi,

I would like to understand the way 'states' are retained across batches while using Database.Stateful.

Example, If I am using 'totalSum'  as variable to be maintained across batches, then I could do one of the following.  Which one of below is more optimal? does the SF makes sure that the 'serialization of execution' is done only when the Line 2 in option 2 used about to be executed?, 
if the serialization is across all the body of execution(), then option-1 and option-2 does not look too different.
 
//Option 1

execute (scope) {
   foreach(myObject__c obj: scope) {
       totalSum += obj.field_to_sum__c; //<== Line 1
   }
}
 
//Option 2

execute (scope) {
   Integer localSum = 0;
   foreach(myObject__c obj: scope) {
       localSum += obj.field_to_sum__c;
   }

 totalSum += localSum;  //<== Line 2
}

 
Vasani ParthVasani Parth
++ . Amit,

Hi,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.For details refer: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm You can check the status of batches processed in apex jobs at : setup|administration setup|Monitoring|Apex jobs
Amit "CLS"  RangariAmit "CLS" Rangari
Parth and Amit C, 

thanks for quick response.  However my question is not about how to use 'StateFul'.

My question is 'how does SF takes care of passing state across one batch to other'. 

In the option 1 in my post, the state-variable totalSum is updated every iteration of loop. 2 batches when want to share the state, the serialization will/should be applied in each loop.

while in option 2 in my post, the state-variable totalSum is used only at the end of the execute method. thus 2 batches when want to share the state, the serialization should be applied only on the last line.

my question is, does SF honours this, giving more parallelizm between batches or does it just run all the batches serially when Stateful is used.
 
Andreas Wolf 25Andreas Wolf 25
You need to use Option 1, as in option 2 you use your "global stateful" variable totalsum outside the execution block
which in return will stay the same across the batchers , because you adding a local not stateful variable localsum;

Amit gave the correct answer, He did not only showed as per sample code in line 2 where you had to declare your stateful variable, he alos gave some directions and help on "what" statefule is.

That kind of answer is way better than the most given answer with a short link or , "oh its a duplicate"
He tried to be helpful and I believ he was.
His statement both will work fine will only work if both varaibales are class variable as like his Integer I
but that wouldn't make sense as your counter only needs one place to be counted.

Stateful has nothing to do with synchron or asynchron ( serial / paralell) it is about keeping the State of a variable
if not stateful you can look at it as the whole thing is just a big iterator except the finish block
(cycle > refresh / clearout > cycle) >finish
whereby if stateful only the execute block is iterating and the declared variables before the block are keeping their state
(declaration > cycle > refresh /clear out only inner execution block>cycle) >finish

Let me being a bit stupid now, looking at you given sample, you might have an option to use rollup instead and SF will do the SUM for you
https://help.salesforce.com/articleView?id=fields_about_roll_up_summary_fields.htm&type=0
I know it might be just a principle question, but i thought just in case, config is still better than code :-)

Hope that helps
Saku ErlaSaku Erla
The result is the same with both options. With very long strings, it helps to add to the member variable only once at the end of execute, as it requires fewer big copy operations on Salesforce servers' side. But that's not critical.

Andreas, the variable isn't out of scope. Also I'd let OP decide if Amit's answer was helpful to them. It really doesn't contain much more information than the (quite terse) official documentation which I'm sure everybody here has already read. Furthermore, walls of text copy-pasted directly from documentation or a blog aren't much more helpful than links to them.

Your explanation of how Stateful works is also a bit off. It works by serializing the class's member variables and recreating the class environment for each call of the execute method, instead of creating a new batch class instance for every call. Nothing else is different. That may be what you intended to say, but I thought I'd clarify it anyway.