Когда мне следует использовать блокировку области (приложение, сервер и т. д.) вместо именованной блокировки в ColdFusion?

StackOverflow https://stackoverflow.com/questions/296721

Вопрос

Когда уместно использовать <cflockscope="application"> или что-то подобное, а не <cflock name="foo">?

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

Это было полезно?

Решение

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

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

Вы захотите заблокировать это с помощью type = " exclusive " ;. Где бы ни использовался application.myData, вам нужен тип = " только для чтения " замок. Исключением является метод 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 и уникальной переменной экземпляра в зависимости от вашего варианта использования.

Другие советы

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

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

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

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

Если честно, так как появление 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)>

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

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

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

  

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

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

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

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

    http://www.horwith.com/index .cfm / 2008 / 4/28 / cflock объясненном

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

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

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

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

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

    Источник: 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>
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top