大约一年前,我问了一个关于我在应用程序中遇到的错误的问题,该错误表明可能存在竞争条件:
在 ColdFusion 中创建结构体时可能存在竞争条件 https://stackoverflow.com/questions/19859690/possible-race-condition-creating-structs-in-coldfusion
一年过去了,我仍然遇到这个应用程序和其他使用相同技术的应用程序的问题,坦率地说,您似乎无法在同一请求中可靠地创建和更新结构。
这当然看起来很可笑,所以我一定做错了什么 - 但我会很感激一些帮助。
这是对正在发生的事情的解释:
- 我有一个在应用程序范围中实例化的函数,它接受逗号分隔的 ID 列表作为参数。
- 该函数访问数据库,请求具有匹配 ID 的所有记录
- 然后,我们循环遍历记录集,并创建一个本地范围的结构,使用记录的 ID 动态命名,例如
Local.myStruct['item_' & myrecordset.ID]
- 最后我们将数据添加到这个结构中。
问题是,代码会间歇性地在最后一步出错,指出前两行创建的动态命名结构不存在......有趣的是,有问题的代码行正在更新结构,并且所以如果它不存在,我希望它简单地创建它 - 我想知道使用数组表示法设置动态命名变量的值是否与使用点表示法的行为不同?
所以,这里有一些代码:
<cffunction name="GetPrices" access="public" returntype="struct">
<cfargument name="ItemID" type="string" required="true" />
<cfargument name="PriceBand" type="string" default="1" />
<cfset var Local = {} />
<!--- Query the database for the part details --->
<cfquery name="Local.GetParts" datasource="#this.sDSN#">
SELECT TOP 200
[ItemID]
, [Price1]
, [Price2]
, [Price3]
FROM [Items]
WHERE 1 = 1
<cfif ListLen(Arguments.ItemID) GT 1>
AND ItemID IN (<cfqueryparam cfsqltype="cf_sql_integer" list="yes" value="#Arguments.ItemID#">)
<cfelse>
AND itemID = <cfqueryparam cfsqltype="cf_sql_integer" value="#Arguments.ItemID#">
</cfif>
</cfquery>
<cfloop query="Local.GetParts">
<cfset Local.ReturnStruct['item_' & Local.GetParts.ItemID] = {} />
<cfset Local.ReturnStruct['item_' & Local.GetParts.itemID].CurrentPrice = Local.GetParts['price' & Arguments.PriceBand] />
</cfloop>
<cfreturn Local.ReturnStruct />
</cffunction>
该函数将这样调用:
Variables.GetPrices = Application.com.Items.GetPrices(
ItemID = '8263,1996,324686,32,12746,297807,1763,37568,2359782,321,3525,563466,323'
, PriceBand = 2
)
正如您所看到的,该函数是 varscoped 的,并且在任何情况下我们都运行 CF10,我相信隐式 Local 作用域在函数中是线程安全的。
Var 范围是我们去年解决这个问题的地方,但可惜问题仍然存在。有人可以提供其他建议吗?
Thanks
EDIT:根据要求,这是我收到的错误的示例:
元素 item_61284 在作为表达式一部分引用的 CFML 结构中未定义。
每次的项目 ID 都不同。可能值得注意的是,出于问题的目的,发布的代码已被稍微操纵 - 因此下面的堆栈跟踪可能会显示无法归因于上面代码的零碎内容。
我确信从生产代码中删除的任何内容都与该问题无关,因为无论使用相同的技术,这些症状都会出现在多个应用程序的数十个功能中。
Coldfusion.runtime.UndefinedElementException:元素 item_61284 在作为表达式一部分引用的 CFML 结构中未定义。在coldfusion.runtime.CfJspPage.ArrayGetAt(CfJspPage.java:974)在coldfusion.runtime.CfJspPage._arrayGetAt(CfJspPage.java:985)在coldfusion.runtime.CfJspPage._arrayGetAt(CfJspPage.java:980)在cfparts2ecfc1041715109$funcREDACTED。 runFunction(REDACTED.cfc:665)在coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)在coldfusion.runtime.UDFMethod $ ReturnTypeFilter.invoke(UDFMethod.java:405)在coldfusion.runtime.UDFMethod $ ArgumentCollectionFilter.invoke (UDFMethod.java:368)在coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)在coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)在coldfusion.runtime.UDFMethod.invoke(UDFMethod.java: 518)在coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:660)在coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:469)在coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2373)在REDACTEDcfm969331649。 runPage(REDACTED.cfm:43)在coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:244)在coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:444)在coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage) .java:2799)在REDACTEDcfm522717774.runPage(REDACTED.cfm:83)在coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:244)在coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:444)在coldfusion .runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2799)在cfapplication2ecfc1345221948$funcONREQUEST.runFunction(REDACTED\Application.cfc:573)在coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)在coldfusion.runtime.UDFMethod$ ReturnTypeFilter.invoke(UDFMethod.java:405)在coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)在coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)在coldfusion.runtime.UDFMethod.runFilterChain (UDFMethod.java:321)在coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)在coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:655)在coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java: 444)在coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:414)在coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:108)在coldfusion.runtime.AppEventInvoker.onRequest(AppEventInvoker.java:300)在coldfusion。 filter.ApplicationFilter.invoke(ApplicationFilter.java:424)在coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)在coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)在coldfusion.filter.PathFilter.invoke (PathFilter.java:112)在coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:94)在coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)在coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java: 38)在coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)在coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)在coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)在coldfusion。 filter.CachingFilter.invoke(CachingFilter.java:62) 在 Coldfusion.CfmServlet.service(CfmServlet.java:219) 在 Coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89) 在 org.apache.catalina.core.ApplicationFilterChain .internalDoFilter(ApplicationFilterChain.java:305)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)在coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)在coldfusion.bootstrap。 BootstrapFilter.doFilter(BootstrapFilter.java:46) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 在太阳.reflect.GenerateMethodAccessor63.invoke(未知来源) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源) 在 java.lang.reflect.Method.invoke(未知来源) 在 com.intergral.fusionreactor.j2ee.filterchain.WrappedFilterChain.doFilter (WrappedFilterChain.java:97) 在 com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doNext(FusionReactorRequestHandler.java:437) 在 com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doHttpServletRequest(FusionReactorRequestHandler.java:311) 在com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doFusionRequest(FusionReactorRequestHandler.java:192)在com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.handle(FusionReactorRequestHandler.java:472)在com.intergral.fusionreactor.j2ee。 filter.FusionReactorCoreFilter.doFilter(FusionReactorCoreFilter.java:36) 在 sun.reflect.GenerateMethodAccessor61.invoke(未知来源) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源) 在 java.lang.reflect.Method.invoke(未知来源)在com.intergral.fusionreactor.j2ee.filterchain.WrappedFilterChain.doFilter(WrappedFilterChain.java:79)在sun.reflect.GenerateMethodAccessor60.invoke(未知来源)在sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)在java.lang。 com.intergral.fusionreactor.agent.filter.FusionReactorStaticFilter.doFilter(FusionReactorStaticFilter.java:53)处的reflect.Method.invoke(未知来源) com.intergral.fusionreactor.agent.pointcuts.NewFilterChainPointCut$1.invoke(NewFilterChainPointCut.java: 41)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java)在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)在org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:169)在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)在org.apache。 catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) 在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java: 118) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:414) 在 org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:204) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler .process(AbstractProtocol.java:539) 在 org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) 在 java.util .concurrent.ThreadPoolExecutor$Worker.run(来源不明) at java.lang.Thread.run(来源不明)