Jim,

Thanks for the example.  A couple comments:

1)  You're correct, writing out and setting the query results could be cleaned up a little, but that's not really the area of my concern.  My area of concern is looping over and reading a query results stored within the application scope.

2)  I tried the two examples you provided.

> <!--- You can either make a copy of this --->
> <cflock scope="application" type="ReadOnly" timeout="10">
>   <cfset qGetItems = duplicate(application.structtest.qGetItems)>
> </cflock>
>
> <cfloop query="qGetItems">
>  <cfoutput>#qGetItems.field# <br></cfoutput>
> </cfloop>

This option works.  Kind of seems strange though.  The entire point of saving something out to the application scope is to let everyone access it and read from it.  If I'm just looping over and reading from the application scope, why would I need to duplicate it per request?  Seems like it could lead to a memory issue if you're trying to store something in the application scope that is being referenced frequently.

> <!--- Or access the variable directly --->
> <cflock scope="application" type="ReadOnly" timeout="10">
>   <cfset qGetItems = application.structtest.qGetItems>
>   <cfloop query="application.structtest.qGetItems">
>       <cfoutput>#qGetItems.field# <br></cfoutput>
>   </cfloop>
> </cflock>

I tried this one and it actually did not work putting a "read only" cflock around it.  It still appears that the iterator or looping mechanism built within "cfloop query" is being shared accross requests.

One work around suggested is to reference the structure like an Array and loop over the results using the array index (i.e. don’t let cold fusion determine the next record set within your query results).

Loop code would look something like:

Note:  261 being the max number of keys within the structure

<cfloop  from="1" to="261" index="i">
<cfoutput>

#qGetItems.Field[i]#

</cfoutput>
</cfloop>

I still am perplexed.  Again, my question is why would CF MX share the iterator when looping (specificaly using cfloop query="") over a query results stored in the applicaition structure?

>In general this really isn't a good way to go about this.
>
>First you're tying your application scope directly to db performance.  I
>would definitely do the query outside of the lock.
>
>Also I'm really confused about why you're quoting on the left side of
>the cfsets - there's no dynamic processing going on so it's just really
>weird.
>
>It doesn't matter if you set the application query to the local variable
>later - since you're assigning a structure you're making a REFERENCE,
>not a copy.  So when you loop over the local variable you're actually
>looping (unlocked) over the application variable.
>
>At least in 4.5 structs aren't automatically generated.  So I
>"StructTest" is supposed to be a struct, it isn't here.  You ARE setting
>"qGetItems" as a struct - but then OVERWRITING it with a query.  What
>you have does not place your result set into a struct - it places it
>into a dotted variable in the application scope.
>
>I would rewrite this something liks this:
>
><cfset AppSet = False>
><cflock scope="application" type="ReadOnly" timeout="10">
>            <cfif NOT IsDefined("application.structtest.qGetItems")>
>                        <cfset AppSet = True>
>            </cfif>
><cflock>
>
><cfif NOT AppSet>
>            <cfquery name="qGetItems" datasource="">
>                        SELECT Field  
>                        FROM Table
>                        ORDER BY Field
>            </cfquery>
>            <cfset StructTest = StructNew()>
>            <cfset StructTest.qGetItems = qGetItems>
>            <cflock scope="application" type="EXCLUSIVE" timeout="10">
>                        <cfset application.StructTest = StructTest>
>            </cflock>
></cfif>
>
>            <!--- You can either make a copy of this --->
><cflock scope="application" type="ReadOnly" timeout="10">
>            <cfset qGetItems =
>duplicate(application.structtest.qGetItems)>
></cflock>
><cfloop query="qGetItems">
>            <cfoutput>#qGetItems.Field# <br></cfoutput>
></cfloop>
>
>            <!--- Or access the variable directly --->
><cflock scope="application" type="ReadOnly" timeout="10">
>            <cfset qGetItems = application.structtest.qGetItems>
>            <cfloop query="application.structtest.qGetItems">
>                        <cfoutput>#qGetItems.Field# <br></cfoutput>
>            </cfloop>
></cflock>
>
>Note that in MX you don't have to be so careful about the locking - in
>fact in this case you might not need it at all, depending on how this is
>used.
>
>Jim Davis
>
>-----Original Message-----
>From: Jason Reuter [mailto:[EMAIL PROTECTED]
>Sent: Friday, November 14, 2003 4:51 PM
>To: CF-Talk
>Subject: Re:Cold Fusion MX - Looping over application Structure
>
>Yes, I'm using cflock.  Here's the code snippet:
>
><html>
><body>
>
><cflock scope="application" type="EXCLUSIVE" timeout="10">
>
><cfif NOT IsDefined("application.structtest.qGetItems")>
>
><cfquery name="qGetItems" datasource="">
>SELECT Field  
>FROM Table
>ORDER BY Field
></cfquery>
>
>
><cfset "application.structtest.qGetItems" = structNew()>
><cfset "application.structtest.qGetItems" = qGetItems>
></cfif>
>
><cfset qGetItems = application.structtest.qGetItems>
>
></cflock>
>
><cfloop query="qGetItems">
><cfoutput>
>
>#qGetItems.Field# <br>
>
></cfoutput>
></cfloop>
>
></body>
></html>
>
>
>
>>You do still need to lock shared scope variables that would have a risk
>of
>>race conditions.  Why you don't run into problems with that on CF 4.5
>is
>>beyond me, but a simple cflock should fix it right up.
>>
>>
>>Timothy Heald
>>Web Portfolio Manager
>>Overseas Security Advisory Council
>>U.S. Department of State
>>571.345.2319
[Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings]

Reply via email to