4

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

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

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

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

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

重要的是:这有效。

然而,发生的事情是非常间歇性地,当引用我们创建的结构中的一个节点时,我们发现它不存在并且 CF 抛出一个错误 - 这可能发生在 1% 的时间并重新加载同一页面,一切将完美地工作。

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

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

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

<!--- 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>标记中 - 类似于:

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

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

所以......抱歉问题的史诗长度,但有人能看到这是怎么发生的吗?

4

1 回答 1

3

从评论回答...

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


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

于 2013-11-12T13:37:44.680 回答