cflock不会为同一浏览器中调用的同一个url抛出超时

时间:2013-10-17 09:50:08

标签: coldfusion locking coldfusion-10 railo cfml

我在页面test.cfm上尝试锁定块,下面是在页面上写的代码。

<cfscript>
writeOutput("Before lock at #now()#");
lock name="threadlock" timeout="3" type="exclusive"
{
    writeOutput("<br/>started at #now()#");
    thread action="sleep"  duration="10000";
    writeOutput("<br/>ended at #now()#");
}
writeOutput("<br/>After lock at #now()#");
</cfscript>

假设我的网页网址为http://localhost.local/test.cfm并在浏览器中以两个不同的标签运行。我期待其中一个url会在3秒后抛出超时错误,因为另一个url因为线程睡眠而至少锁定了10秒。令人惊讶的是,我没有得到任何超时错误,而是在第一次调用完成执行后10秒后第二次页面调用运行。

但我附加一些url参数(例如http://localhost.local/test.cfm?q=1)会抛出错误。此外,我在不同的浏览器中调用相同的URL,然后其中一个调用将抛出超时问题。

是否基于会话和网址锁定?

更新 以下是两种不同情况的输出:

案例1:

TAB1 网址:http://localhost.local/test/test.cfm

 Before lock at {ts '2013-10-18 09:21:35'} 
 started at {ts '2013-10-18 09:21:35'} 
 ended at {ts '2013-10-18 09:21:45'} 
 After lock at {ts '2013-10-18 09:21:45'}

TAB2 网址:http://localhost.local/test/test.cfm

Before lock at {ts '2013-10-18 09:21:45'} 
started at {ts '2013-10-18 09:21:45'}
ended at {ts '2013-10-18 09:21:55'} 
After lock at {ts '2013-10-18 09:21:55'}

案例2:

TAB1 网址:http://localhost.local/test/test.cfm

 Before lock at {ts '2013-10-18 09:27:18'} 
 started at {ts '2013-10-18 09:27:18'} 
 ended at {ts '2013-10-18 09:27:28'} 
 After lock at {ts '2013-10-18 09:27:28'}

TAB2 网址:http://localhost.local/test/test.cfm? (最后添加?)

Before lock at {ts '2013-10-18 09:27:20'} 
A timeout occurred while attempting to lock threadlock.
The error occurred in C:/inetpub/wwwroot/test/test.cfm: line 13
11 : 
12 : <cfoutput>Before lock at #now()#</cfoutput>
13 : <cflock name="threadlock" timeout="3" type="exclusive">
14 :    <cfoutput><br/>started at #now()#</cfoutput>    
15 :    <cfthread action="sleep"  duration="10000"/> 
...

案例2的结果符合预期。

对于案例1,我刚才注意到的奇怪的事情是tab 2输出“在{ts'2013-10-18 09:21:45'锁定之前}表示整个请求在10秒后开始(表示完全执行后第一个标签)当我在第一个标签的2秒之后将其在第二个URL中解雇时。

1 个答案:

答案 0 :(得分:1)

之前我在Chrome中看到过这种行为。如果一个选项卡正在执行对给定URL的请求,则其他选项卡将等待第一个选项卡完成,然后立即返回。

以下是我能够在Chrome浏览器中一致复制的概念验证。

foo.cfm

<cfoutput>#now()#</cfoutput>
<cfscript>
    sleep(5000);
</cfscript>
<cfoutput>#now()#</cfoutput>

在浏览器中打开两个标签到foo.cfm。

Test1 :尽可能快地执行下一个序列而不会出错。单击tab1,选择URL栏,然后按Enter键。单击tab2,选择URL栏,然后按Enter键。

执行此操作时,您会注意到第一页中的时间戳相隔5秒,您会注意到第二页上的时间戳甚至没有开始,直到第一页完成。

Test2 :尽可能快地执行下一个序列而不会出错。单击tab1,按ctrl + f5,单击tab2,按ctrl + f5。

现在,请注意tab 2将在tab1之后几乎完成,时间戳表明处理发生的时间等于切换标签所用的持续时间。

如果您也使用f5,则会出现相同的行为。因此,基本上它是对Chrome浏览器(以及可能的其他人)的微优化,以便不对其他选项卡已经在处理的资源进行额外的http请求。我的假设,我还没有测试过,如果资源要返回正确的浏览器缓存HTTP标头,那么第二个请求将使用第一个请求结果。