在 ColdFusion 中创建结构的可能竞争条件 [英] Possible race condition creating Structs in ColdFusion

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

问题描述

当我使用相同的方法(不是相同的代码)时,我一直在我一直在研究的几个系统中看到间歇性错误,这使我相信问题可能与在同一系统中创建和使用结构有关要求.我想知道是否可能存在竞争条件?

I've been seeing intermittent errors in a couple of systems I've been working on, when using the same methodology (not the same code) leading me to believe the problem may be linked to creating and using structs in the same request. I'm wondering if it's possible there's a race condition?

场景是这样的:我们在一个电子商务系统上,查看一个产品,或者在某些情况下是一个产品列表.有问题的代码旨在返回与每个产品相关联的图像,在我们可以用来显示所述图像的结构中.

The scenario is this: We're on an e-commerce system, looking at a product, or in some cases a list of products. The code in question is designed to return the images associated with each product, in a struct that we can use for display of said images.

在请求开始时,代码会查找与相关项目关联的数据库记录.这些记录代表产品的图像.这些记录在单个 CFQuery 调用中返回(或更准确地说,对返回 CFQuery 调用结果的函数的调用,形成一个包含各种信息的结构).

At the beginning of the request, the code looks for database records associated with the item in question. These records represent images for the product(s). These records are returned in a single CFQuery call (or more accurately, a call to a function which returns the results of a CFQuery call, shaped into a struct containing various info).

然后代码循环通过提供的图像结构,并将各种信息添加到本地结构.稍后在请求中,我们使用结构中的数据在 <img> 标记中显示图像.我们还使用 data- 属性填充 <img> 标记以用于 JavaScript.

The code then loops through the supplied image struct, and adds various information to a Local struct. Later in the request we use the data in the struct to display the images in our <img> tags. We also populate the <img> tag with data- attributes for use with JavaScript.

如果查询未正确返回任何特定图像 - 通常是因为物理文件丢失 - 我们使用通用占位符图像.这是通过将结构创建放在 try/catch 块中来完成的.

In the case that any particular image was not correctly returned by the query - usually because the physical file is missing - we use a generic placeholder image. This is done by putting the struct creation inside a try/catch block.

重要的是:这行得通.

然而,发生了什么,非常间歇地,当引用我们创建的结构中的一个节点时,我们发现它不存在并且 CF 抛出一个错误 - 这可能发生 1%时间并重新加载同一页面,一切都会完美运行.

What's happening however, is that very intermittently, when referring to a node in the struct we've created, we find that it does not exist and CF throws an error - this happens maybe 1% of the time and reloading the same page, everything will work perfectly.

我在多个系统、多个服务器、不同版本的 ColdFusion(具体来说是 8 和 10)上遇到了同样的问题,并且使用完全不同的代码来实现类似的结果.我看到这个问题的第一个系统,实际上使用 FileExists 来检查图像文件是否可用,因此我认为问题可能是由文件系统的瓶颈引起的 - 我尝试了很多方法来解决这个问题并最终在新系统中完全消除了它 - 但问题仍然存在.

I've had this same problem on multiple systems, on multiple servers, on different versions of ColdFusion (8 & 10 to be specific) and using completely different code to achieve similar results. The first system I saw this issue on, actually used FileExists to check that the image file was available and thus I thought that the problem was probably caused by the bottleneck of the filesystem - I tried many ways around this and eventually eliminated it altogether in the new system - but the problem persists.

我唯一能想到的是,当创建一个结构然后在同一个请求中稍后使用该结构时,可能会发生竞争条件;我在结构完成创建之前引用了结构中的一个节点.不过我在这里没有使用线程,所以我真的看不出这是怎么可能的……我没有其他想法.

The only thing I can think of, is that when creating a struct and then using that struct later in the same request, there's a possibility that a race condition occurs; whereby I refer to a node in the struct before it's finished being created. I'm not using threading here though, so I can't really see how that's possible... I'm out of other ideas.

下面的一些代码显示了我在做什么,但鉴于相同的问题出现在完全不同的系统上,我认为是方法而不是代码有问题.

Some code is below to show what I'm doing, but given that the same issue arises on completely different systems, I think it's the methodology rather than the code that has a problem.

<!--- Get product images --->
<cfset Local.stProductImages = Application.cfcParts.getPartImages(
        l_iItemID = Arguments.pid
) />


<!--- Loop through images --->
<cfloop list="#ListSort(structKeyList(Local.stProductImages['item_' & Arguments.pid]), 'text')#" index="i">
    <cftry>
        <cfset Local['ImageURL_' & i & '_Large']    = Local.stProductImages['item_' & Local.arguments.pid][i].large_watermarked.URL />
        <cfcatch>
            <cfset Local['ImageURL_' & i & '_Large']    = Application.com.Images.getMissingImages().large />
        </cfcatch>
    </cftry>                        
    <cftry>
        <cfset Local['ImageURL_' & i & '_Med']      = Local.stProductImages['item_' & Local.arguments.pid][i].med.URL />
        <cfcatch>
            <cfset Local['ImageURL_' & i & '_Med']      = Application.com.Images.getMissingImages().med />
        </cfcatch>
    </cftry>                        
    <cftry>
        <cfset Local['ImageURL_' & i & '_Small']        = Local.stProductImages['item_' & Local.arguments.pid][i].small.URL />
        <cfcatch>
            <cfset Local['ImageURL_' & i & '_Small']        = Application.com.Images.getMissingImages().small />
        </cfcatch>
    </cftry>                        

    <img class          = "altProdImg<cfif i EQ 'image_03'> endImage</cfif>" 
        src             = "#Local['ImageURL_' & i & '_Small']#" 
        image           = "#i#" 
        alt             = ""
        data-imgsmall   = "#Local['ImageURL_' & i & '_Small']#"
        data-imgmed     = "#Local['ImageURL_' & i & '_Med']#"
        data-imglarge   = "#Local['ImageURL_' & i & '_Large']#"
        data-imgnum     = "#i#"
        data-pid        = "#Arguments.pid#"
    />
</cfloop>

当引用前面代码中创建的节点时,<img> 标记中发生错误 - 类似于:

The error occurs in the <img> tag, when referring to a node created in the preceding code - Something like:

元素 ImageURL_image_02_Large 在类型为coldfusion.runtime.LocalScope 的Java 对象中未定义.

Element ImageURL_image_02_Large is undefined in a Java object of type class coldfusion.runtime.LocalScope.

但只是偶尔...我会重新加载,每次都能完美运行.

But only very occasionally... I'll reload and it'll work perfectly every time.

所以...抱歉问题太长了,但有人能看出这是怎么发生的吗?

So... sorry for the epic length of question, but can anybody see how this could occur?

推荐答案

从评论中回答...

Answer from comments...

您描述的行为是非 var 作用域的症状,因此它可能像在 cfloop 标记中使用 index="local.i" 一样简单(您只需要在编写时进行作用域变量).

The behaviour you describe is symptomatic of not var scoping, so it might be as simple to fix as using index="local.i" in the cfloop tag (you only need the scoping when writing the variable).


旁注: 一个相对简单的方法来检查你是否在一个函数中,而不通过代码,是抛出一个错误(即 <cfthrow message="where am i?"/>) 然后检查堆栈跟踪 - 如果你看到像 coldfusion.runtime.UDFMethod$funcSTUFF.runFunction(filename:line) 这样的东西,你知道你在一个函数中(即使你所在的模板没有任何迹象).


Side note: A relatively easy way to check if you're in a function, without going through code, is by throwing an error (i.e. <cfthrow message="where am i?" />) then check the stack trace - if you see stuff like coldfusion.runtime.UDFMethod or $funcSTUFF.runFunction(filename:line) you know you're inside a function (even when the template you're in shows no sign of it).

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

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