Блокировка здесь кажется разумной, но это не то место, и вы не блокируете доступ к файлу исключительно.Вы должны заблокировать всю транзакцию, т.е. заблокировать прямо перед получением 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>
(Вам, вероятно, следует также добавить некоторую обработку ошибок, если она не просто не указана в вашем фрагменте.)
Пояснение
Каждый поток остановится на cflock
и спросите семафор copyFileLock
, работает ли он в данный момент.Если нет, поток продолжит, извлекает файлы и копирует их.Пока все это копирование выполняется (семафор "работает"), все остальные потоки, которые встречают cflock
, будут поставлены в очередь, поэтому приостановите выполнение и дождитесь семафора (в вашем случае каждый поток в очереди будет ждать 3600 секундчтобы семафор дал «идти», или иначе просто забудь об этом и выйди).После завершения операции копирования в первом потоке семафор перестанет «работать» и проверит очередь.Если в это время другие потоки были поставлены в очередь, следующий поток в очереди возобновит выполнение, промыть и повторить.
Эксклюзивная блокировка гарантирует, что поток никогда не "увидит" состояние неполного файла (= fetch aфайл, который собирается скопировать другой поток).