In addition to the sfdcfox answer, this simple example shows how static variables are not part of the viewstate, even if you are doing Ajax refreshes
But first, a word from the doc on static variables:
They aren’t transmitted as part of the view state for a Visualforce page.
Here's a controller with a static counter and an instance variable (viewstate) counter:
public with sharing class SFSE282798 {
public static Integer staticCounter {
get {
if (staticCounter == null) {
staticCounter = 0;}
return staticCounter;
}
private set;
}
public Integer viewStateCounter {
get {
if (viewStateCounter == null) {viewStateCounter = 0;}
return viewStateCounter;
}
private set;
}
public SFSE282798() {}
public void doCount() { //action method for VF page
staticCounter++;
viewStateCounter ++;
}
}
and here's the VF page:
<apex:page id="SFSE282798" controller="SFSE282798">
<apex:form>
<apex:commandButton value="Count" action="{!doCount}">
<apex:actionSupport reRender="counters" event="onclick"/>
</apex:commandButton>
<p></p>
<apex:outputPanel id="counters">
<apex:outputText value="static counter: {!staticCounter}"/>
<p></p>
<apex:outputText value="viewstate counter: {!viewStateCounter}"/>
</apex:outputPanel>
</apex:form>
</apex:page>
Now, the page looks like this when initially displayed:
click the button once ...
click a few more times
Since the static variable isn't part of the view state, each button click instantiates a new controller instance (i.e. static variable is null, init'd to zero when 'getters' execute, then incremented to 1
on action method invocation).
It doesn't matter if the static variable is in the controller or in a related class.
The viewstate is how VF communicates state of the interactions between the browser and the server. Salesforce limits viewstate size to optimize that interaction between the two remote computers.
The transaction scope is the life between when the controller action starts and the controller action returns.