|
|
On Apr 1, 3:10 am, GArlington <garling...@xxxxxxxxxxxxx> wrote:
> On Mar 31, 9:13 pm, aadams <aad...@xxxxxxxxxxxxx> wrote:
>
>
>
> > I have a bunch of CFCs cached into the application scope that I use
> > throughout my app. One particular CFC (dao.cfc) handles my data
> > interface (read, write, execute, etc...). I also have other CFCs
> > loaded into the application scope that call these application.dao
> > functions.
>
> > My problem is that my function's data seem to randomly overlap each
> > other. For example, I have a routine that prints invoices. The user
> > selects a list of orders and clicks a button. On the action page I
> > loop through each selected order and flag them as invoiced as well as
> > assign them an invoice number and a few other things, then I finally
> > print the invoices. The reads from the database are all done through
> > application.dao.read().
>
> > This normally works fine. However, today (and a couple times in the
> > past) a user encountered a problem when printing a handful of
> > invoices. The problem occurred in a totally separate CFC that handles
> > per screen security. The function that failed (also in the
> > application scope) simply does an application.dao.read() and returns a
> > query object with the screen's security record from the database.
> > (see code below).
> > ***************************************************************
> > <!--- application.security.getScreenByID()--->
> > <cffunction name="getScreenByID" access="public"
> > returntype="query" hint="I return the screen for the given screen ID."
> > output="false">
> > <cfargument name="screenID" required="yes" type="numeric">
> > <cflock type="exclusive" name="getScreenID" timeout="1">
> > <cfset this.screen = application.dao.read(sql="
> > SELECT s.file_name, s.name,
> > s.display_order,s.status, s.file_name,
> > m.name,m.screens_ID,m.module_directory
> > FROM screens s
> > LEFT OUTER JOIN modules m on m.ID = s.modules_ID
> > WHERE s.ID = " & arguments.screenID
> > )>
> > </cflock>
>
> In the above code you set cfc GLOBAL variable "this.screen" to the
> session/screen specific value. If any other user is going to use the
> same function 1.5 seconds after the current user started your variable
> will be overwritten with new values for ALL sessions using this cfc.
> It is ALWAYS better to define instance data in function-local
> variables - i.e. <cfset VAR thisIsFunctionLocalVar =
> application.dao.read(...) />
> In this case each call to this function will generate new and unique
> value that you can return from the function...
>
>
>
> > <!--- if field doesn't exist, dump for debugging --->
> > <cfif not isDefined('this.screen.file_name')>
> > <cfdump var="#this.screen#" label="Screen Query">
> > <cfdump var="#arguments#" label="arguments passed to
> > getScreenByID">
> > <cfabort>
> > </cfif>
> > <cfreturn this.screen />
>
> > </cffunction>
> > ***************************************************************
> > The error that the user encountered indicates that a field in the
> > query just performed in the security CFC doesn't exist. To
> > troubleshoot I added the cfif block that tests for the existence of
> > the field "file_name" and if it doesn't exist it cfdumps the query and
> > function arguments. To my surprise today the dumped data was a query
> > from the print invoices routine.
>
> > Now, as you can see below I use the "this" scope to scope the "screen"
> > query variable,
>
> "this" scope is GLOBAL for ALL invocations of the same cfc in current
> JVM.
>
> > but somehow this is being overwritten with the query
> > from an entirely different CFC method. The variable names aren't even
> > the same, so why does it return the invoice query in the screen query?
>
> You will have to clarify that in order for me to explain why it
> happens.
>
>
>
> > This has happened in other CFCs that call the application.dao.read()
> > function. Should this not be in the application scope? Should I
> > cflock these application.function calls? I'm stumped, any help is
> > appreciated.
>
> > By the way, I'm on CFMX 7.0.2 standard on RedHat using MySQL 5.
>
> Once again:
> set ALL variables in functions to be function-local <cfset VAR
> thisIsFunctionLocalVar = ... />
> [<cfset thisIsCFCGlobalVar = ... /> <cfset
> this.thisIsAnotherCFCGlobalVar = ... />]
> this will help you to avoid overwriting the data via different calls...
Thanks for the reply. I have changed the variables to local as you
suggested, but still get the same results. The <cfdump var="#screen#"
label="Screen Query"> ends up dumping a query from a totally different
CFC with a totally different variable name. In fact the queries that
end up overwriting the screen variable are local vars from other CFC
functions.
Now, maybe I'm doing it wrong. In CFCs I'm using application scoped
functions from dao.cfc. So, does this make even the local vars in a
function writable by dao.cfc?
|
|