当从CFC中包含CFM时,可能会出现并发和作用域问题

6

我正在将一个组件放置在我的应用程序范围内,以便它可以在所有请求之间共享,并且它包含一个cfm模板:

<cfcomponent output="false">

    <cffunction name="run" output="false" returntype="void">

        <cfset var tmp = false/>

        <cftry>
            <cfinclude template="inc.cfm"/>
            <cfcatch>
                <cffile action="append"
                        file="#ExpandPath("error.log")#"
                        output="ERROR: #cfcatch.message#"/>
            </cfcatch>
        </cftry>

    </cffunction>

</cfcomponent>

被包含的模板仅仅创建了一个数组并检查数组长度是否符合要求,如果不符合,则会写入到error.log文件中。
<cfset tmp = [
    "one",
    "two",
    "three"
]/>
<cfif ArrayLen(tmp) neq 3>
    <cffile action="append"
            file="#ExpandPath("error.log")#"
            output="Length = #ArrayLen(tmp)#"/>
</cfif>

如果我在它上面运行负载(100个并发线程),那么以下内容会出现在我的error.log文件中...

ERROR: element at position 3 of array variable &quot;___IMPLICITARRYSTRUCTVAR0&quot; cannot be found.
Length = 0
Length = 2

注意 我在Java 1.7.0_09上使用ColdFusion 9.0.1.274733。我已经在相同的JRE上测试了Railo,并且它可以正常工作。


附加信息 下面的内容也会导致问题,将tmp变量更改为结构体并添加一个随机项到variables范围中,但该项未被引用...

<cfcomponent output="false">

    <!--- 
    Some random variable that does nothing with the exception
    of being the facilitator of my eternal pain
    --->
    <cfset variables.t = {}/>

    <cffunction name="run" output="false" returntype="void">

        <cfset var tmp = {}/>

        <cftry>
            <cfinclude template="inc2.cfm"/>
            <cfcatch>
                <cffile action="append"
                        file="#ExpandPath("error.log")#"
                        output="ERROR: #cfcatch.message#"/>
            </cfcatch>
        </cftry>

    </cffunction>

</cfcomponent>

这包括一个模板,与第一个非常相似,长这样...
<cfset tmp.arr = [
    "one",
    "two",
    "three"
]/>
<cfif ArrayLen(tmp.arr) neq 3>
    <cffile action="append"
            file="#ExpandPath("error.log")#"
            output="Length = #ArrayLen(tmp.arr)#"/>
</cfif>

如果您从variables范围中删除该项,则它可以正常工作。如果在模板中转储#variables##local#,则所有内容都应该在您期望的位置。

(来自评论的更新)

我已经将此问题提升为bug#3352462


2
这里的任何链接与 https://duckduckgo.com/?q="___IMPLICITARRYSTRUCTVAR0" 有任何相关性吗? - Peter Boughton
是的,看起来它可能指向类似的问题,找得好。 - Stuart Wakefield
1
仅在使用数组的简写表示法时才会受到影响,使用ArrayNew(1)并逐个设置每个项目似乎可以按预期工作。 - Stuart Wakefield
2
自 CF8 以来,隐式语法存在问题。http://www.barneyb.com/barneyblog/2009/06/19/coldfusion-struct-literals-are-not-thread-safe-cfml-ones-are/ http://www.barneyb.com/barneyblog/2008/07/14/coldfusion-struct-literals-fail-again/ - Leigh
3个回答

4

这是基于Peter / 你自己的评论。

自从CF8引入语法以来,数组和结构体简写表示法存在许多错误。Adobe修复它们的方法有点像打地鼠,而不是努力彻底解决问题。看起来你发现了另一个例子。不过很有趣的是,我知道他们在CF10的开发周期中修复了一些问题,所以它是否仍然存在于CF10中还有待观察。

唯一的解决方法是在出现这些问题的情况下不使用该符号表示法。

请您提bug以便Adobe注意到这个问题?

此外,稍微值得注意的是,与您在此处的特定问题无关:CF尚未支持Java 1.7。您可能需要记住这一点。


谢谢。是的,似乎ColdFusion做了一些非常奇怪的事情来支持缩写。无论如何,我已经将其作为错误#3352462提出... https://bugbase.adobe.com/index.cfm?event=bug&id=3352462 - Stuart Wakefield

0
在你的第一个例子中,如果你将tmp声明为数组而不是布尔值,会有什么区别吗?
<cfset var tmp = ArrayNew(1) />

而不是...

<cfset var tmp = false />

0
您可能需要在您的 <tag> 标签周围添加一些锁定,以确保只有一个请求被允许修改该文件。

理想情况下,如果文件按预期工作,则不应该对其进行任何更改。因此,这并没有解决原始问题。 - Stuart Wakefield

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接