Должен ли я <CFLOCK>а? - PullRequest
       51

Должен ли я <CFLOCK>а?

0 голосов
/ 16 февраля 2019

Просматривая какой-то старый код, который время от времени истекает, я наткнулся на этот CFLOCK вокруг запуска CFFILE COPY внутри CFLOOP.

Имеет ли смысл использование 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>

1 Ответ

0 голосов
/ 16 февраля 2019

Блокировка здесь кажется разумной, но это не то место, и вы не блокируете доступ к файлу исключительно.Вы должны заблокировать всю транзакцию, т.е. заблокировать прямо перед получением 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файл, который собирается скопировать другой поток).

...