The original reasoning for not using exclusive locking:
All of the many concurrent requests want to ONLY read the data - no problem
if using read locks.
If you put an Exclusive (write) lock than you have to wait until all other
locks are released.
That is all requests would have to go through the bottle neck of the
exclusive lock one by one.
Now if you do really want to write then yes an exclusive lock is needed but
if you just want to check if the data is initialised then just get a read
lock to ensure you are not getting the data in the middle of an update. 

The only issue is if BETWEEN releasing the read lock and obtaining the
exclusive lock other requests could also flag the data as not initialised
and queue for an exclusive lock to initialise the data - since getting the
read lock and checking for the structure being defined is a very quick
operation AND this only happening when Application variables timeout or on a
server reboot AND no harm done as the structure is only initialised again

SoOoOo it's not a problem... my version of the code is:
In app_globals:

<cflock scope="Application" type="ReadOnly" ...>
        <CFSET Init = (NOT isDefined("Application.MyStruct") OR Not
isStruct(Application.MyStruct))>
</cflock>
<CFIF Init>
        <cflock scope="Application" type="exclusive" ...>
                <CFSET Application.MyStruct = StructNew()>
                ...read data here into Application.MyStruct  for some
time....
        </cflock>
</CFIF>

In Index.cfm:

<CFINCLUDE template="app_locals.cfm">
<cflock scope="Application" type="ReadOnly" ...>

        ... rest of body of index.cfm
        switch fuesaction ...
        case ...
        case ...

</cflock>

No pointers or duplicates etc.

Hope this clears it up,
Noam

        ----------
        From:  Scott Talsma [SMTP:[EMAIL PROTECTED]]
        Sent:  Tuesday, 29 August 2000 11:48
        To:  [EMAIL PROTECTED]
        Subject:  RE: No more need for cflock!!

        I seem to remember (from an OS class) a work-around to the double db
read.
        One uses two locks: one application lock, one named lock.


        <cflock scope="Application" type="exclusive" ...>
                <cfparam name="Application.Initialized" default=FALSE>
                <cfif NOT Application.Initialized>
                        <cflock NAME="lockname" type="exclusive" ...>
                                <read data here for some time....>
                                <cfset Application.Initialized = TRUE>
                        </cflock>
                </cfif>
        </cflock>

        1) When Thread1 starts initializing the data, it has both locks
        2) Thread2 starts, and also detects that the data must be
initialized.  It
        waits on Thread1.
        3) Thread1 finishes, sets Application.Initialized, and unlocks both
locks
        4) Thread2 gets the first lock, checks Application.Initialized,
        and then exits, without reading the data a second time.

        When the initialization requires more that a few seconds, this keep
the
        cfserver and/or db from bogging down.

        --Scott

        -----Original Message-----
        From: BOROVOY Noam [mailto:[EMAIL PROTECTED]]
        Sent: Dienstag, 29. August 2000 10:12
        To: [EMAIL PROTECTED]
        Subject: RE: No more need for cflock!!


        Well I'll take a race any day instead of a deadlock ;-)
        Think about it in a different way - the worst case would be that two
threads
        detect the structure is not defined and then:
        The first acquires a write lock (blocking any others from reading
and
        detecting it's not defined)
        Writes the data
        Releases the lock.
        The second acquires a write lock
        Writes the SAME data
        Releases the lock.

        It's not really a critical race since both outcomes are the same
regardless
        of who "wins" all you get is a very remote chance of a performance
hit - two
        hits on the DB - when you reboot your server.

        Bottom line  - don't worry be :-).


                ----------
                From:  Dustin Breese [SMTP:[EMAIL PROTECTED]]
                Sent:  Monday, 28 August 2000 18:57
                To:  [EMAIL PROTECTED]
                Subject:  RE: No more need for cflock!!

                Whopps...good catch....

                However, you still get a race condition where multiple
threads can
                initialize the code.  If you exit the read lock with a
pre-chosen
        path to
                initialize, then multiple threads can decide to initialize
and will
        simply
                wait their turn in the queue before initializing.

                Am I missing something else?  (Highly likely!)

                An exclusive lock isn't optimal, so what is the solution?
Maybe the
        second
                body needs to do another check wrapped inside the EXCLUSIVE
lock to
        make
                sure it still is not defined?  That case would seem to catch
any of
        the
                threads that slipped past, right?

                -Dustin


                -----Original Message-----
                From: BOROVOY Noam [mailto:[EMAIL PROTECTED]]
                Sent: Monday, August 28, 2000 10:30 AM
                To: [EMAIL PROTECTED]
                Subject: RE: No more need for cflock!!


                Careful,
                Can't do that - see below:

                        ----------
                        From:  Dustin Breese [SMTP:[EMAIL PROTECTED]]
                        Sent:  Monday, 28 August 2000 18:09
                        To:  [EMAIL PROTECTED]; Fusebox
                        Subject:  RE: No more need for cflock!!

                        Steve,

                        Only suggestion I would make here is to put the
        initialization code
                inside
                        the CFLOCK -- it keeps multiple threads from running
the
        same init
                logic.
                        Probably a low possibility, but it could definitely
happen
        in a
                        high-transaction environment.  Just in case the init
logic
        is a
                big-hitter!

                        For example:

                        <cflock name="#application.applicationname#"
timeout="60"
                type="readonly">
                                <cfif not
isdefined("application.requestapp")>
                                        <!--- DO THE INIT LOGIC WITHIN THE
LOCK, NOT
        WITHOUT
                --->
                        Here you need to have a write lock NOT a read lock -
but you
        can't
                acquire one because you've already read locked

                        Instead - First check if the variable is defined -
does not
        require
                a lock -if it's not then Write lock and Init

                                </cfif>

                                <cfset request.app=application.requestapp>
                        </cflock>

                        Just my 2-cents!
                        -Dustin

                        -----Original Message-----
                        From: Steve Nelson [mailto:[EMAIL PROTECTED]]
                        Sent: Saturday, August 26, 2000 8:34 AM
                        To: Fusebox
                        Subject: No more need for cflock!!


                        I've just hit upon a technique that would mean we
only ever
        need to
                use
                        cflock two times in a fusebox home application. This
is for
                application
                        variables, session and server variables would need
to do the
        same
                too i
                        imagine (personally i never use them)

                        First I want to propose a new filename,
qry_globals.cfm the
        point of
                the
                        file is to store application wide queries, it would
sit in
        the root
                        directory of your home application.  It would run
queries
        from the
                        database upon booting up the server then store the
variables
        into
                        memory.  This massively reduces stress on the
database,
        generally
                it's
                        an excellent technique.  The problem has been with
cflock.
        people
                        forget to use it and CF WILL blow up on you if you
forget to
        use
                        CFLOCK.  So I figured out a way to bypass all the
cflock
        nonsense
                and
                        only require two cflocks in your entire application,
which
        do very
                small
                        tasks.

                        Check this code out.  It's wicked cool  (Hal let me
know how
        I did
                on my
                        fusedocs, i'm just starting to get into them, and
love 'em!
        :)

                        <cfsetting enablecfoutputonly="yes">
                        <!--- qry_globals.cfm --->
                        <!---
                        || I start by doing a check to see if the variable
                        application.requestapp exists if this
                        || variable exists then I set
        request.app=application.requestapp and
                I
                        do not rerun any
                        || application wide queries.  If this variable does
not
        exist I
                rerun
                        all the queries
                        || and set application.requestapp=request.app

                        ||
                        || Then anytime I want one of these values I call it
as:
                        request.app.queryname instead
                        || of application.queryname.  By doing this I no
longer need
        to use
                        cflock in anywhere
                        || other than this file.

                        || [EMAIL PROTECTED]

                        ||
                        -->
                        <-- request.app - this is a copy of an application
variable
        called
                        application.requestapp
                        ++> application.requestapp - this is where all
application
        wide
                queries
                        sit
                        +++
                        --->
                        <cfset request.maindsn="valuemusiclocal">
                        <cfapplication name="blbl"
                        applicationtimeout="#createtimespan(0,1,0,0)#">
                        <cflock name="#application.applicationname#"
timeout="60"
                        type="readonly">
                                <cfif isdefined("application.requestapp")>
                                        <cfset
request.app=application.requestapp>
                                        <cfset runrequest="no">
                                <cfelse>
                                        <cfset runrequest="yes">
                                </cfif>
                        </cflock>
                        <cfif runrequest>
                                <cfset request.app=structnew()>
                                <cfquery name="request.app.getstates"
                datasource="#request.maindsn#">
                                        select * from states
                                        where active=1
                                        order by state_name
                                </cfquery>
                                <cfset request.app.state_rows=structnew()>
                                <cfloop query="request.app.getstates">
                                        <cfset
        request.app.state_rows[state_id]=currentrow>
                                </cfloop>
                                <cflock name="#application.applicationname#"
        timeout="60"
                        type="exclusive">
                                        <cfset
application.requestapp=request.app>
                                </cflock>
                        </cfif>
                        <cfsetting enablecfoutputonly="no">





                        <!--- dsp_address.cfm --->
                        <!---
                        || I'm demonstrating the use of a request.app
variable, note
        that
                        || I do not need cflock, and I do not need to rerun
the
        getstates
                query

                        || [EMAIL PROTECTED]

                        ||
                        -->
                        <--
                        ++> request.app.getstates - this is a query with all
the
        states in
                it
                        +++
                        --->
                        <select name="state_id">
                        <cfoutput query="request.app.getstates">
                                <option value="#state_id#">#state_name#
                        </cfoutput>
                        </select>


                        Now that's a beautiful thing! eh?

                        Steve


        
----------------------------------------------------------------------------
                        --
                        To Unsubscribe visit


        
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
                        send a message to [EMAIL PROTECTED]
with
                'unsubscribe' in
                        the body.



        
----------------------------------------------------------------------------
                        --
                        To Unsubscribe visit


        
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
                        send a message to [EMAIL PROTECTED]
with
                'unsubscribe' in
                        the body.




        
----------------------------------------------------------------------------
                --
                        To Unsubscribe visit

        
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
                send a message to [EMAIL PROTECTED] with
        'unsubscribe' in
                the body.

        
----------------------------------------------------------------------------
                --
                To Unsubscribe visit

        
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
                send a message to [EMAIL PROTECTED] with
        'unsubscribe' in
                the body.



        
----------------------------------------------------------------------------
        --
                To Unsubscribe visit
        
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
        send a message to [EMAIL PROTECTED] with
'unsubscribe' in
        the body.
        
----------------------------------------------------------------------------
        --
        To Unsubscribe visit
        
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
        send a message to [EMAIL PROTECTED] with
'unsubscribe' in
        the body.

        
----------------------------------------------------------------------------
--
        To Unsubscribe visit
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
send a message to [EMAIL PROTECTED] with 'unsubscribe' in
the body.
------------------------------------------------------------------------------
To Unsubscribe visit 
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or send a 
message to [EMAIL PROTECTED] with 'unsubscribe' in the body.

Reply via email to