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

时间:2013-11-08 12:57:33

标签: coldfusion struct race-condition intermittent

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

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

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

然后代码循环遍历提供的图像结构,并将各种信息添加到Local结构中。在请求的后面,我们使用结构中的数据在<img>标签中显示图像。我们还使用<img>属性填充data-标记,以便与JavaScript一起使用。

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

重要的是:这有效。

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

我在多个系统上,在多个服务器上,在不同版本的ColdFusion(特定于8&amp; 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对象中未定义。

但只是非常偶尔......我会重新加载,每次都会完美运作。

所以...对于史诗般的长度问题感到抱歉,但有人能看出这种情况会怎样吗?

1 个答案:

答案 0 :(得分:3)

回答评论......

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


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