Why the duplicate <cfif...> block?

<cfif not structKeyExists(application,
"myObj")>
   <cflock name="#application.applicationName#_myObj"
type="exclusive" timeout="30">
       <cfif not structKeyExists(application,"myObj")>
           ... build a local myObj and do all your initialization ...
           <cfset application.myObj = myObj />
       </cfif>
   </cflock>
</cfif>

one inside and one outside of the <cflock...>?

Is this because of the potential that someone else just edged you out and actually set the application variable while you were setting your lock?
Bill

On 5/28/05, Sean Corfield <[EMAIL PROTECTED]> wrote:
On 5/28/05, Jeff Anderson <[EMAIL PROTECTED]> wrote:
> <cflock> helps prevents race conditions and you SHOULD use it when writing
> to the application scope (and even when reading depending on the
> circumstances).

Well, maybe. It depends. For just setting a simple value like a DSN
string, there is no race condition so you could ignore locking. You
almost never need locks for reading these days (although it does
indeed depend on how you construct the code that writes to the scope
elsewhere in your application).

> since you are instantiating the DAO only once (and setting the value to
> variables.dsn only once) there cant really be a race condition within the
> CFC. the value will always be the same.

Right. Locking is harmless in this case but will potentially slow down the app.

A good pattern for locking on initialization is:

<cfif not structKeyExists(application,"myObj")>
    <cflock name="#application.applicationName#_myObj"
type="exclusive" timeout="30">
        <cfif not structKeyExists(application,"myObj")>
            ... build a local myObj and do all your initialization ...
            <cfset application.myObj = myObj />
        </cfif>
    </cflock>
</cfif>

By only doing the one assignment to the shared variable, at the end of
the initialization, you ensure that reading is safe elsewhere in your
application.

The simplest approach is:

<cfset application.myObj = createObject("component","MyObj").init(args) />

Note the create-and-initialize pattern. init() should return 'this':

<cfreturn this />

Do *not* do this instead:

<cfset application.myObj = createObject("component","MyObj") />
<cfset application.myObj.init(args) />

That is unsafe - other threads may see application.myObj is defined
and try to use it *before* (or during) the call to init() - very
dangerous! Either use the one line form above or use a page local
variable like this:

<cfset myObj = createObject("component","MyObj") />
<cfset myObj.init(args) />
<cfset application.myObj = myObj />

Hope that helps - there's a lot of confusion about multithreaded programming!
--
Sean A Corfield -- http://corfield.org/
Team Fusebox -- http://fusebox.org/
Got Gmail? -- I have 50, yes 50, invites to give away!

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood


----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email to [email protected] with the words 'unsubscribe cfcdev' as the subject of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting (www.cfxhosting.com).

CFCDev is supported by New Atlanta, makers of BlueDragon
http://www.newatlanta.com/products/bluedragon/index.cfm

An archive of the CFCDev list is available at www.mail-archive.com/[email protected]





--
[EMAIL PROTECTED]
http://blog.rawlinson.us

If you want Gmail - just ask. ----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email to [email protected] with the words 'unsubscribe cfcdev' as the subject of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting (www.cfxhosting.com).

CFCDev is supported by New Atlanta, makers of BlueDragon
http://www.newatlanta.com/products/bluedragon/index.cfm

An archive of the CFCDev list is available at www.mail-archive.com/[email protected]

Reply via email to