我是不是该 一个 ?

问题描述 投票:2回答:1

查看一些偶尔超时的旧代码,我在CFLOOP内围绕CFFILE COPY运行时遇到了这个CFLOCK。

使用CFFLOCK是否有意义或似乎是必要的?该文件正在从一个位置复制到新创建的文件夹,然后将其压缩以供将来下载。

起初,我只是要增加锁定的超时,但后来我开始盯着它,想知道这是不是一个错误。

<cfloop query="LOCAL.qDocsZip">
<cflock name="copyFileLock" timeout="3600" type="readonly">
<cffile action="copy"
source="#ExpandPath(LOCAL.qDocsZip.file_location)#"     
destination="#LOCAL.zip_new_path#/#LOCAL.qDocsZip.original_file_name#">
</cflock>
</cfloop>
coldfusion coldfusion-9
1个回答
2
投票

锁定在这里似乎是合理的,但它不是正确的位置,你不是特别锁定文件访问。您应该锁定整个事务,即在获取LOCAL.qDocsZip之前锁定。这样,您可以确保要复制的文件仅由单个线程触及,并且不会与另一个线程发生并发。在这方面:cflock是一个特定于JVM的信号量,因此它无法保证系统级别的事务安全性,例如:如果您有其他程序可以并行访问您的文件。

这是它应该是什么样子:

<!--- only one thread at a time can execute the code within this lock (exclusive named lock) --->
<cflock name="copyFileLock" timeout="3600" type="exclusive">

    <!--- fetch files to copy in this transaction --->
    <cfquery name="LOCAL.qDocsZip" ...>
        ...
    </cfquery>

    <!--- copy all the files --->
    <cfloop query="LOCAL.qDocsZip">
        <cffile action="copy" ...>
    </cfloop>

</cflock>

(你应该添加一些错误处理,如果这不仅仅在你的代码片段中遗漏了。)

Explanation

每个线程将停在cflock并询问信号量copyFileLock它是否正在“运行”。如果没有,线程将继续,获取文件并复制它们。当整个复制正在进行时(信号量正在“运行”),遇到cflock的每个其他线程都将排队,因此暂停执行并等待信号量(在您的情况下,每个排队的线程将等待3600秒信号量给“去”,或者只是忘记它并退出)。在第一个线程上完成复制操作后,信号量将停止“运行”并检查队列。如果其他线程在此期间排队,队列中的下一个线程将继续执行,冲洗并重复。

独占锁将确保线程永远不会“看到”不完整的文件状态(=获取即将被另一个线程复制的文件)。

© www.soinside.com 2019 - 2024. All rights reserved.