This whole locking thing sounds like a fine topic at the Fusebox dev con, or
in a separate room at the big CF dev con. I better check the event schedule,
it could already be on the list...
Alan McCollough
Web Programmer
Allaire Certified ColdFusion Developer
Alaska Native Medical Center
> -----Original Message-----
> From: BOROVOY Noam [SMTP:[EMAIL PROTECTED]]
> Sent: Tuesday, August 29, 2000 2:33 AM
> To: [EMAIL PROTECTED]
> Subject: RE: No more need for cflock!!
>
> 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.
------------------------------------------------------------------------------
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.