Inside your methods (<cffunction>) use scoping.

For example.
        <cffunction name="DoSomeAction" output="no" returntype="any">
                <cfargument name="RecordID" required="yes" type="numeric">
                <cfset var local = StructNew() />

                <cfset local.GetRecord =
Application.Functions.GetRecordFromRecordID(arguments.RecordID)>
                
                <!--- HERE IS THE PROBLEM: arguments.RecordID doesn't always
match GetRecord.RecordID  --->
                                
                <cfreturn local.Whatever>
        </cffunction>
-----Original Message-----
From: Tavs Dalaa [mailto:[email protected]] 
Sent: Saturday, October 15, 2011 8:47 AM
To: cf-talk
Subject: Amazingly annoying concurrent CFC variable issue


I've got some pretty simple CFC code which fails when executed with 10+
concurrent connections. Variables between requests get mixed up, so one
request with recordID 10 suddenly returns with recordID 2 etc, causing
issues in the application.

This is simplified version of code:

application.cfm

<cfapplication name="OurApp" applicationtimeout="#CreateTimeSpan(0,1,0,0)#">
<cfset Application.functions =
createObject("component","com.ourapp.functions").init() />

functions.cfc

<cfcomponent displayname="Our functions">
        <cffunction name="init" output="false" returntype="any"
access="public">
                <cfreturn this />
        </cffunction>

        <cffunction name="DoSomeAction" output="no" returntype="any">
                <cfargument name="RecordID" required="yes" type="numeric">
                
                <cfset GetRecord =
Application.Functions.GetRecordFromRecordID(arguments.RecordID)>
                
                <!--- HERE IS THE PROBLEM: arguments.RecordID doesn't always
match GetRecord.RecordID  --->
                                
                <cfreturn Whatever>
        </cffunction>
        
        <cffunction name="GetRecordFromRecordID" output="no"
returntype="any">
                <cfargument name="RecordID" required="yes" type="numeric">
                
                <cfquery name="GetRecord"
datasource="#Application.AppDatasource#">
                        SELECT RecordID,RecordTitle FROM Records
                        WHERE RecordID = <cfqueryparam
value="#arguments.RecordID#" cfsqltype="CF_SQL_NUMERIC">
                </cfquery>
                                
                <cfreturn GetRecord>
        </cffunction>
</cfcomponent>

index.cfm

<cfset ActionResult = Application.Functions.DoSomeAction(URL.RecordID)>


Now, pretty simple, and tons of irrelevant code removed. 

If we fire 50 requests at the same moment to index.cfm, like:

index.cfm?RecordID=1
index.cfm?RecordID=2
.. 
..

.. Then within the DoSomeAction function, we see that 1 out of 25 requests
on average there's a mixup, we get a result for a different record than the
one we requested.

Tried to wrap in CFLOCK, eg:

<cflock name="Lockname" timeout="15" type="exclusive">
        <cfset GetRecord =
Application.Functions.GetRecordFromRecordID(arguments.RecordID)>
</cflock>

.. no diff.

Tried to Var and cflock, ie:

<cflock name="Lockname" timeout="15" type="exclusive">
        <cfset Var GetRecord =
Application.Functions.GetRecordFromRecordID(arguments.RecordID)>
</cflock>

Any ideas? 



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
Order the Adobe Coldfusion Anthology now!
http://www.amazon.com/Adobe-Coldfusion-Anthology/dp/1430272155/?tag=houseoffusion
Archive: 
http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:348184
Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm
Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm

Reply via email to