Когда следует использовать блокировку области (приложение, сервер и т. Д.) По сравнению с именованной блокировкой в ​​ColdFusion? - PullRequest
11 голосов
/ 17 ноября 2008

Когда целесообразно использовать или это похоже на ?

В частности, я заинтересован в использовании CFLock для защиты общих объектов в приложениях, сеансах или областях сервера, но мне также интересно узнать о различных применениях блокировки в ColdFusion.

Ответы [ 6 ]

10 голосов
/ 17 ноября 2008

Вы должны использовать при чтении и записи из вещей, которые могут измениться в области применения. Например:

<cfquery name="application.myData">
    select * from myTable
</cfquery>

Вы хотите заблокировать это с помощью type = "exclusive". Везде, где используется application.myData, вам нужна блокировка type = "readonly". Исключением является метод OnApplicationStart Application.cfc, который блокируется сам. Аналогичным образом используйте ту же стратегию с областями сеансов и серверов.

Именованные блокировки дают вам больше контроля над стратегией блокировки. Используйте именованный cflock, когда вам нужно динамически заблокировать команды. Например:

<cflock name="write_file_#session.user_type#" type="exclusive">
    <cffile action="write" name="file_#session.user_type#" output="#content#" />
</cflock>

В этом примере пользователям разных типов разрешено писать файл одновременно, но пользователи с одинаковым session.user_type должны ждать друг друга. Этот cflock помогает избежать проблем с конфликтами файлов.

Еще одна причина использовать именованную блокировку - если вы не знаете сферу действия вашей текущей операции. Если вы находитесь в экземпляре cfc, как вы узнаете, в какой области вы были созданы? Переменные? Сессия? Заявка? Хорошая инкапсуляция учит нас тому, что объекты не знают ничего, кроме того, что им было сказано. Внутри CFC используйте именованную блокировку и назовите ее после CFC или CFC и уникальной переменной экземпляра в зависимости от вашего варианта использования.

2 голосов
/ 19 ноября 2008

опираясь на другие предложения здесь.

Если честно, так как появление cf8 и теперь duplicate () могут дублировать объекты, я бы использовал блокировки областей только при записи в приложение, сеанс или область сервера (кстати, запись в область сервера - большая проблема нет в моей книге).

если вам нужно прочитать данные, я бы использовал duplicate () для глубокого копирования данных в локальную переменную и избежания блокировки чтения все вместе. это предотвратит тупики.

<cflock scope="application" timeout="5" type="exlusive">
 <cfset application.data = {}>
 <cfset application.data.firstname = "tony">
</cflock>

<cfset variables.firstname = duplicate(application.data.firstname)>
2 голосов
/ 18 ноября 2008

Продолжая с того, что @Mr. Нейт сказал, используйте замки, когда вас беспокоят условия гонки. Например, вы можете заблокировать инициализацию сеанса, но не последующие чтения. Точно так же вы можете заблокировать запись в область приложения, но не чтение.

Блокировка чтения намного менее полезна, так как CF6, который представил поточно-ориентированные области общих переменных. В старые добрые времена, если вы не были осторожны, вы могли одновременно читать и записывать один и тот же адрес памяти. Однако, поскольку CF стал Java-поддержкой, это не проблема.

Именованные блокировки полезны, как он продемонстрировал, для блокировки всего, что не ограничено, например, чтение / запись файла.

1 голос
/ 04 марта 2012

Отличное время для использования именованной блокировки - это когда у вас есть «транзакция», в которой вы хотите убедиться, что все происходит за один раз, например, обновление нескольких таблиц в базе данных одновременно, или когда вы просто хотите убедиться, что два пользователя не обновляют одну и ту же запись базы данных одновременно или при чтении или записи в файл на сервере, который может иметь одновременно несколько пользователей, пытающихся получить к нему доступ.

Проще говоря, в любое время возникает ситуация, когда могут возникнуть проблемы, если два запроса попытались сделать одно и то же одновременно, а затем установить именованную блокировку вокруг него (или если это строго связано с областью сеанса, приложения или сервера). , затем используйте замок с ограничением по объему).

Бен Надель опубликовал запись в блоге, в которой говорилось:

"Как я понимаю, должны быть выполнены ДВА условия, чтобы использование CFLock:

  1. Доступ к общему ресурсу осуществляется или обновляется.
  2. Должна существовать вероятность того, что состояние гонки приведет к отрицательному результату. "

Вы можете даже вкладывать теги CFLOCK, например, иметь именованную блокировку вокруг транзакции и блокировки на уровне сеанса или приложения, вложенные внутрь, но делайте это с осторожностью - если вы сделаете это неправильно, у вас может возникнуть «тупиковая» ситуация где ни один запрос не может выполнить заблокированный раздел страницы, и все запросы к заблокированному разделу страницы могут быть заблокированы до истечения времени ожидания. (Руководство ColdFusion описывает лучшие методы для вложенной блокировки.)

0 голосов
/ 17 июля 2013

Это пример из документации ColdFusion 8, в которой переменная страницы используется для создания «локального флага», который можно прочитать без блокировки, чтобы убедиться, что переменные приложения были инициализированы.

Это означает, что нам нужно условно исключить блокировку, потому что ее запуск при каждой загрузке страницы может создать узкие места из-за того, что блокировка занимает больше времени на обработку.

Я не знаю, появились ли лучшие методы с тех пор, как это произошло, но я полагаю, что все равно выложу здесь. Документы ColdFusion часто не дают хорошего кода, поэтому мне интересно узнать, может ли кто-нибудь увидеть, как этот код можно улучшить.

  • Я мог бы поместить локальный флаг в область запроса, чтобы он был доступен даже в пользовательских тегах и т. Д. Однако он действительно нужен только в app.cfm, поэтому, возможно, в этом нет необходимости.
  • Я бы также удалил isDefined () в пользу structKeyExists (), чтобы ему не приходилось перебирать все области видимости.
  • Я бы также использовал скобочные обозначения для установки переменных, чтобы сохранить заглавные буквы (например, application ['myDsn'] = "orders"). Это также облегчает поиск переменных записей, которые немного важнее чтения переменных. (Это мое предпочтение)

Источник: http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=sharedVars_18.html

<!--- Initialize local flag to false. --->
<cfset app_is_initialized = False>
<!--- Get a readonly lock --->
<cflock scope="application" type="readonly">
    <!--- read init flag and store it in local variable --->
    <cfset app_is_initialized = IsDefined("APPLICATION.initialized")>
</cflock>
<!--- Check the local flag --->
<cfif not app_is_initialized >
<!--- Not initialized yet, get exclusive lock to write scope --->
    <cflock scope="application" type="exclusive">
        <!--- Check nonlocal flag since multiple requests could get to the
                exclusive lock --->
        <cfif not IsDefined("APPLICATION.initialized") >
            <!--- Do initializations --->
            <cfset APPLICATION.varible1 = someValue >
             ... 
            <!--- Set the Application scope initialization flag --->
            <cfset APPLICATION.initialized = "yes">
        </cfif>
    </cflock>
</cfif>
0 голосов
/ 17 ноября 2008

Как правило, вы всегда должны использовать cflock для переменных сеансов, приложений и серверов каждый раз, когда вы читаете или изменяете эти переменные вне Application.cfc, чтобы предотвратить условия гонки. Вот статья, которая может быть полезна:

http://www.horwith.com/index.cfm/2008/4/28/cflock-explained

Редактировать: Чтобы ответить на ваш вопрос о области действия, я всегда использую <cflock scope="application"> (например), когда взаимодействует с общими ресурсами.

...