在同一请求中创建和更新结构时可能的竞争条件 - coldfusion [英] Possible race conditions when creating and updating a struct in the same request - coldfusion

查看:172
本文介绍了在同一请求中创建和更新结构时可能的竞争条件 - coldfusion的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大约一年前,我问了一个问题,我在一个应用程序中得到的错误,表明可能的竞争条件:



在ColdFusion中创建Structs的可能的竞争条件



一年来,我仍然有这个和其他应用程序的问题,使用相同的技术,并且坦率地说,你不能在同一请求中可靠地创建和更新结构。
这当然看起来很可笑,所以我必须做错事 - 但我会感谢一些帮助。



这里是对发生了什么的解释: / p>


  • 我有一个函数,在应用程序范围中实例化,接受以逗号分隔的ID列表作为参数。

  • 函数命中数据库,请求具有匹配ID的所有记录

  • 然后我们循环遍历记录集,并创建一个局部范围的结构,使用记录的ID动态命名,例如 Local.myStruct ['item_'& myrecordset.ID]

  • 最后,我们向此结构中添加数据。



问题是,间歇性地,代码将错误的最后一步,说明动态命名的结构,创建字面上两行前,不存在...有趣的是,有问题的代码行是更新struct,所以如果它不存在,我会期望它简单地创建它 - 我想知道如果使用数组符号设置动态命名的变量的值不同于使用点表示法不同?



所以,这里有一些代码:

 < cffunction name =GetPricesaccess =public returntype =struct> 
< cfargument name =ItemIDtype =stringrequired =true/>
< cfargument name =PriceBandtype =stringdefault =1/>

< cfset var Local = {} />

<!---查询数据库的零件明细--->
< cfquery name =Local.GetPartsdatasource =#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_integerlist =yesvalue =#Arguments.ItemID#>)
< cfelse>
AND itemID =< cfqueryparam cfsqltype =cf_sql_integervalue =#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,我会导致相信一个隐式的本地范围是线程安全的函数。
var scoping是我们去年在这个问题上着陆的地方,但是问题仍然存在。任何人都可以提出任何其他建议吗?



感谢



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。在coldfusion.runtime.UDFMethod处的coldFusion.runtime.UDFMethod $ ReturnTypeFilter.invoke(UDFMethod.java:405)at coldfusion.runtime.UDFMethod $ ArgumentCollectionFilter.invoke(UDFMethod.java:472)runFunction(REDACTED.cfc: (UDFMethod.java:321)在coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:UDFMethod.java:368)在coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)在coldfusion.runtime.UDFMethod.runFilterChain 518)at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:660)在coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:469)在coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2373)在REDACTEDcfm969331649。运行在coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:244)在coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:444)的runPage(REDACTED.cfm:43) .java:2799)在coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:244)在coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:444)在coldfusion(REDACTED.cfm:在coldfusion.runtime.UDFMethod()处的coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)上的.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2799)at cfapplication2ecfc1345221948 $ funcONREQUEST.runFunction(REDACTED\Application.cfc:573) $ returnTypeFilter.invoke(UDFMethod.java:405)at coldfusion.runtime.UDFMethod $ ArgumentCollectionFilter.invoke(UDFMethod.java:368)在coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)在coldfusion.runtime.UDFMethod。运行在coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java)中的coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:655)上的coldFusion.runtime.UDFMethod.invoke(UDFMethod.java:220)中的runFilterChain(UDFMethod.java:321) :444)at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:414)在coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:108)在coldfusion.runtime.AppEventInvoker.onRequest(AppEventInvoker.java:300)在冷灌注.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)at coldfusion.filter.NatacheFilter.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)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)at sun.reflect.GeneratedMethodAccessor63.invoke(未知源)at sun.reflect.DelegatingMethodAccessorImpl.invoke(未知源)at java.lang.reflect.Method.invoke(未知源)at com.intergral.fusionreactor.j2ee.filterchain.WrappedFilterChain。 doFilter(WrappedFilterChain.java:97)at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doNext(FusionReactorRequestHandler.java:437)at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doHttpServletRequest(FusionReactorRequestHandler.java:311)在com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doFusionRequest(FusionReactorRequestHandler.java:192)at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.handle(FusionReactorRequestHandler.java:472)at com.intergral.fusionreactor.j2ee .filter.FusionReactorCoreFilter.doFilter(FusionReactorCoreFilter.java:36)at sun.reflect.GeneratedMethodAccessor61.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source) )at com.intergral.fusionreactor.j2ee.filterchain.WrappedFilterChain.doFilter(WrappedFilterChain.java:79)at sun.reflect.GeneratedMethodAccessor60.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang .reflect.Method.invoke(未知源)在com.intergral.fusionreactor.agent.filter.FusionReactorStaticFilter.doFilter(FusionReactorStaticFilter.java:53)at 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(Unknown Source)at java.lang.Thread.run(Unknown Source)



方案

Gary,我感到你的痛苦,因为我也经历过各种疯狂的CF错误,不应该是可能的。我花了几个月的时间来争论在Transfer ORM中的间歇性失败,我最近刚刚学到的是由于xmlSearch()不是线程安全的!



因此,让我分享几个策略,不会解决您的问题,但会帮助您更接近诊断问题的根本原因:



使用duplicate()消除线程安全问题



将xmlSearch()的结果包装在duplicate()中。这可能不是这里的问题,但您可以尝试拆分的结构键的生成从使用,如:

  cfloop query =Local.GetParts> 
< cfset local.id =item_&重复(Local.GetParts.ItemID)/>
< cfset Local.ReturnStruct [local.id] = {CurrentPrice:Local.GetParts ['price'& Arguments.PriceBand]} />
< / cfloop>

使用cflog 进行健全性检查



这可能是我最好的策略,因为它告诉你条件,CF是在当它正在barf。尝试类似:

 < cfloop query =Local.GetParts> 
< cfset Local.ReturnStruct ['item_'& Local.GetParts.ItemID] = {} />
< cftry>
< cfset Local.ReturnStruct ['item_'& Local.GetParts.itemID] .CurrentPrice = Local.GetParts ['price'& Arguments.PriceBand] />
< cfcatch type =any>
< cflog file =crazy.logtext =GetParts:#currentRow#/#local.getParts.recordCount#,KeyCount:#structKeyCount(local.ReturnStruct)#,keys:#structKeyList(local.ReturnStruct )#/>
< / cfcatch>
< / cftry>
< / cfloop>

< cfreturn Local.ReturnStruct />

这个想法是,当遇到意外错误时,记录您认为可能有助于推断信息关于你在哪里。 Bonus:这实际上不会向用户抛出一个错误。



PS - 我注意到的一件事是如果你的查询不返回结果,Local.ReturnStruct将未定义。我个人会在函数的开头定义它:< cfset local.returnStruct = {} />


About a year ago I asked a question about errors I was getting in an app, that indicated a possible race condition:

Possible race condition creating Structs in ColdFusion

A year on, I'm still having issues with this and other apps where the same technique is employed and it seems that frankly, you cannot create and update a struct reliably in the same request. This of course seems ludicrous, so I must be doing something wrong - but I'd appreciate some help.

Here's an explanation of what's going on:

  • I have a function, instantiated in the Application scope, that accepts a comma separated list of IDs as a parameter.
  • The function hits the database requesting all the records with matching IDs
  • We then loop through the recordset, and create a locally scoped struct, dynamically named using the ID of the record, e.g. Local.myStruct['item_' & myrecordset.ID]
  • Finally we add data to this struct.

The issue is that very intermittently, the code will error on the last step, stating that the dynamically named struct that was created literally two lines previous, does not exist... Interestingly, the line of code in question is updating the struct, and so if it didn't exist, I'd expect it to simply create it - I wonder if using Array notation to set the value of dynamically named variables somehow behaves differently than using dot notation?

So, here's some code:

<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>

The function would be called thus:

Variables.GetPrices = Application.com.Items.GetPrices(
        ItemID      = '8263,1996,324686,32,12746,297807,1763,37568,2359782,321,3525,563466,323'
    ,   PriceBand   = 2
)

As you can see, the function is varscoped, and in any case we're running CF10 where I'm lead to believe that an implicit Local scope is thread safe in a function. Var scoping is where we landed last year on this problem, but alas the problem persists. Can anyone offer any other suggestions?

Thanks

EDIT: As requested, here's an exmple of the errors I'm receiving:

Element item_61284 is undefined in a CFML structure referenced as part of an expression.

The item ID is different every time. It's probably worth noting that the code posted has been manipulated slightly for the purposes of the question - so the stacktrace below may show bits and pieces that can't be attributed to the code above.

I'm confident that nothing removed from the production code is relevant to the issue, as these symptoms occurr across tens of functions in multiple apps, wherever the same technique is used.

coldfusion.runtime.UndefinedElementException: Element item_61284 is undefined in a CFML structure referenced as part of an expression. at coldfusion.runtime.CfJspPage.ArrayGetAt(CfJspPage.java:974) at coldfusion.runtime.CfJspPage._arrayGetAt(CfJspPage.java:985) at coldfusion.runtime.CfJspPage._arrayGetAt(CfJspPage.java:980) at cfparts2ecfc1041715109$funcREDACTED.runFunction(REDACTED.cfc:665) at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472) at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405) at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368) at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55) at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321) at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:518) at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:660) at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:469) at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2373) at REDACTEDcfm969331649.runPage(REDACTED.cfm:43) at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:244) at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:444) at coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2799) at REDACTEDcfm522717774.runPage(REDACTED.cfm:83) at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:244) at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:444) at coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2799) at cfapplication2ecfc1345221948$funcONREQUEST.runFunction(REDACTED\Application.cfc:573) at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472) at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405) at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368) at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55) at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321) at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220) at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:655) at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:444) at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:414) at coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:108) at coldfusion.runtime.AppEventInvoker.onRequest(AppEventInvoker.java:300) at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:424) at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48) at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) at coldfusion.filter.PathFilter.invoke(PathFilter.java:112) at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:94) at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28) at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46) at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62) at coldfusion.CfmServlet.service(CfmServlet.java:219) at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42) at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at sun.reflect.GeneratedMethodAccessor63.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.intergral.fusionreactor.j2ee.filterchain.WrappedFilterChain.doFilter(WrappedFilterChain.java:97) at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doNext(FusionReactorRequestHandler.java:437) at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doHttpServletRequest(FusionReactorRequestHandler.java:311) at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.doFusionRequest(FusionReactorRequestHandler.java:192) at com.intergral.fusionreactor.j2ee.filter.FusionReactorRequestHandler.handle(FusionReactorRequestHandler.java:472) at com.intergral.fusionreactor.j2ee.filter.FusionReactorCoreFilter.doFilter(FusionReactorCoreFilter.java:36) at sun.reflect.GeneratedMethodAccessor61.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.intergral.fusionreactor.j2ee.filterchain.WrappedFilterChain.doFilter(WrappedFilterChain.java:79) at sun.reflect.GeneratedMethodAccessor60.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.intergral.fusionreactor.agent.filter.FusionReactorStaticFilter.doFilter(FusionReactorStaticFilter.java:53) at com.intergral.fusionreactor.agent.pointcuts.NewFilterChainPointCut$1.invoke(NewFilterChainPointCut.java:41) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:414) at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:204) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

解决方案

Gary, I feel your pain because I too have experienced all kinds of crazy CF errors that "shouldn't be possible". I spent literally years battling intermittent failures in the Transfer ORM which I just recently learned was due to the fact that xmlSearch() is not thread-safe!

So, let me share a couple of strategies which will not solve your problem but will help you get closer to diagnosing the underlying cause of the issue:

Use duplicate() to eliminate thread-safety issues

The solution to my XML case above was to wrap the results of xmlSearch() in a duplicate(). It may not be the issue here but you might try breaking apart the generation of the struct key from the usage like:

<cfloop query="Local.GetParts">
    <cfset local.id = "item_" & duplicate(Local.GetParts.ItemID) />
    <cfset Local.ReturnStruct[local.id] = {CurrentPrice: Local.GetParts['price' & Arguments.PriceBand]} />
</cfloop>

Use a sanity check with cflog

This is probably my best strategy because it tells you the condition that CF is in when it's about to barf. Try something like:

<cfloop query="Local.GetParts">
    <cfset Local.ReturnStruct['item_' & Local.GetParts.ItemID] = {} />
    <cftry>
        <cfset Local.ReturnStruct['item_' & Local.GetParts.itemID].CurrentPrice = Local.GetParts['price' & Arguments.PriceBand] />
         <cfcatch type="any">
             <cflog file="crazy.log" text="GetParts: #currentRow#/#local.getParts.recordCount#, KeyCount: #structKeyCount(local.ReturnStruct)#, keys: #structKeyList(local.ReturnStruct)#" />
         </cfcatch>
    </cftry>
</cfloop>

<cfreturn Local.ReturnStruct />

The idea being that when you encounter an unexpected error, log everything you think that might help you deduce information about where you're at. Bonus: this won't actually throw an error to the user.

PS - one thing I noticed is if your query doesn't return results, Local.ReturnStruct would be undefined. I personally would define it at the start of the function like: <cfset local.returnStruct = {} />

这篇关于在同一请求中创建和更新结构时可能的竞争条件 - coldfusion的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆