将会话变量中的值读入Coldfusion中的局部变量

时间:2014-11-19 15:37:50

标签: coldfusion

我真的希望你能帮助我。 我通常将会话变量读入局部变量,这样我就不必创建无限的读锁。 但我遇到了一些有趣的行为。请注意,为简洁起见,我没有应用任何写锁:

请考虑以下事项:


示例1:

<cfset session.testvalue = 1 />
<cfset lcktestvalue = session.testvalue />
<cfoutput>#lcktestvalue#</cfoutput><br />
<cfset session.testvalue = 2 />
<cfoutput>#lcktestvalue#</cfoutput>

输出:

1
1


示例2:

<cfset session.testvalue1.item = 1 />
<cfset lcktestvalue1 = session.testvalue1 />
<cfoutput>#lcktestvalue1.item#</cfoutput><br />
<cfset session.testvalue1.item = 2 />
<cfoutput>#lcktestvalue1.item#</cfoutput>

输出:

1
2


我想弄清楚为什么第二个例子,更新'lcktestvalue1.item',当值只读一次? 我本来期待的例子1&amp; 2产生相同的输出,以下产生第二个例子的输出:


示例3:

<cfset session.testvalue1.item = 1 />
<cfset lcktestvalue1 = session.testvalue1 />
<cfoutput>#lcktestvalue1.item#</cfoutput><br />
<cfset session.testvalue1.item = 2 />
<cfset lcktestvalue1 = session.testvalue1 />
<cfoutput>#lcktestvalue1.item#</cfoutput>

输出:

1
2


我能想到的这种行为的唯一原因是第二个例子,它使用了一个结构内部的结构。 但是,我无法扩展这个概念。你能? 我真的需要理解这一点,因为我正在创建一个购物车,它广泛使用了示例2中的方法。它实际上工作正常,但我不知道为什么,我担心在负载下,它可能会失败?< / p>

感谢您提供给我的任何帮助。

3 个答案:

答案 0 :(得分:9)

因为你的第二个例子是从原始值到新值的指针或引用。你可以想到它是两者之间的一个虚构的字符串,当一个被改变时 - 另一个也是如此。结构会发生这种情况。你可以通过使用副本来解决这个问题。

但请注意!近十年来,不需要过度使用cflock会话/ app / server变量。您仍然需要担心竞争条件,但99%的情况下,这不是您的担忧。

答案 1 :(得分:6)

查尔斯,这是预期的行为。结构和对象通过引用传递 - 这意味着您实际上只是设置指向内存位置的指针以获取底层对象。当set语句处理原语(字符串,数字,日期等)时,它将数据复制到新变量中 - 所以这个:

<Cfset session.testvalue = 1/>
<cfset testvalue = session.testvalue/>

...实际上创建了两个位置,每个位置包含一个“1”

当你处理一个对象时(结构,组件,函数,查询等 - 任何 not primitive ),如下所示:

<cfset session.testvalue.item1 = 1/>
<cfset testvalue = session.testvalue/>

variables.testvalue 变量实际上是指向您在set语句中创建的结构的指针(session.testvalue.item1隐含地创建了一个结构)。

这是重要的基本内容 - 尤其是在处理CFC,功能,应用范围等时。Primitive vs complex variables上的这篇文章更详细地解释了它。

顺便说一句,它与锁定无关。除非你有一些可证明的竞争条件,否则你不需要过度锁定。

我会注意到你在这里的做法可能不是一个好主意 - 你可能应该将你的本地变量作为 variables.varName 以任何方式确定在这种情况下将会话变量推送到该范围不会保存你有任何努力。

注意:在我写这篇文章的过程中,Ray简短地回答了一个简短的答案(当时我很啰嗦)。

注意2:在ColdFusion中有一个细微差别,有些人发现意外 - 数组按值(作为副本)传递,而不是通过引用传递。这有时会让你失望 - 如果你曾经做过一系列的对象

答案 2 :(得分:0)

如果要复制/克隆结构而不仅仅是对存储在SESSION中的对象进行引用,则应使用Duplicate()。

    <cfset session.testvalue1.item = 1 />
    <cfset lcktestvalue1 = Duplicate(session.testvalue1) />
    <cfoutput>#lcktestvalue1.item#</cfoutput><br />
    <cfset session.testvalue1.item = 2 />
    <cfoutput>#lcktestvalue1.item#</cfoutput>

输出

    1
    1

Coldfusion WikiDocs