Double-checked Locking

Mark Kruger has a nice article (with mention from Sean Corfield) on APPLICATION variable locking.

Sean basically added that in the initial example (BAD code) if 2 users hit the condition at the same time, only one will have a lock on the code while the other will wait. The problem lies in the fact that the 2nd user is waiting for the lock to expire, then they will perform a write operation NOT checking the condition again!

The article is here.

BAD code snippet:

1
2
3
4
5
6
7
8
9
<cfif NOT isDefined('Application.curIps')OR IsDefined('url.forceAp')>
  <cflock scope="APPLICATION" timeout="1">
    <cfscript>
      curIps = queryNew("IP");
      queryAddRow(curIps);
      querySetCell(curIps,"IP",cgi.remote_addr);
      Application.curIps = curIps;
    </cfscript>
  </cflock>  

GOOD code snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--- check condition --->
<cfif NOT isDefined('Application.curIps') OR IsDefined('url.forceAp')>
>!--- Use a named lock --->
<cflock name="ipInitialize" timeout="1" type="exclusive">
  <!--- check to make sure condition is still true --->
  <cfif NOT IsDefined('Application.curIps') OR IsDefined('url.forceAp')>
    <cfscript>
         curIps = queryNew("IP");
        queryAddRow(curIps);
        querySetCell(curIps,"IP",cgi.remote_addr);
        Application.curIps = curIps;
   </cfscript>  
</cfif>  
</cflock>  
</cfif>

Another useful mention is that this seems redundant when using CFMX7 due to applicationOnStart in application.cfc unless you want to restart the application manually

Comments