2008-11-17 14 views
11

Kiedy należy użyć < cflock scope = "application" > lub jest to ilk w przeciwieństwie do < cflock name = "foo" >?Kiedy należy używać blokowania zasięgu (aplikacja, serwer itp.) W porównaniu do nazwanego blokowania w ColdFusion?

W szczególności jestem zainteresowany wykorzystaniem CFLock do ochrony obiektów wspólnych w zakresie aplikacji, sesji lub serwerów, ale jestem również zainteresowany poznaniem różnych zastosowań blokowania w ColdFusion.

Odpowiedz

10

Powinieneś używać podczas czytania i pisania rzeczy, które mogą ulec zmianie w zakresie aplikacji. Na przykład:

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

Będziesz chciał zablokować to za pomocą type = "exclusive". Wszędzie tam, gdzie używana jest application.myData, potrzebujesz blokady typu = "readonly". Wyjątkiem jest metoda OnApplicationStart Application.cfc, która blokuje się. Podobnie zastosuj tę samą strategię z zakresami sesji i serwera.

Wymienione zamki zapewniają większą kontrolę nad strategią blokowania. Użyj nazwanego cflock, gdy chcesz dynamicznie blokować polecenia. Na przykład:

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

W tym przykładzie, użytkownicy różnych typów mogą zapisać plik w tym samym czasie, ale użytkownicy z tego samego session.user_type musi czekać na siebie. To cflock pomaga uniknąć problemów z rywalizacją plików.

Innym powodem użycia nazwanej blokady jest brak znajomości zakresu bieżącej operacji. Jeśli jesteś w instancji cfc, skąd wiesz, do jakiego zakresu został utworzony instancja? Zmienne? Sesja? Podanie? Dobra enkapsulacja uczy nas, że przedmioty nie wiedzą nic poza tym, co im powiedziano. Wewnątrz CFC użyj nazwanego zamka i nadaj mu nazwę po CFC lub CFC i unikalnej zmiennej instancji w zależności od przypadku użycia.

+0

Może chcesz być ostrożny wyłączny zakres szerokiego blokowania - może szybko stać się wąskim gardłem wydajności. – modius

0

Zwykle powinieneś zawsze używać cflock dla sesji, aplikacji i vars serwera za każdym razem, gdy czytasz lub zmieniasz te vary poza aplikacją Application.cfc, aby zapobiec warunkom wyścigu. Oto artykuł, który może być pomocny:

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

Edit: Aby dodatkowo odpowiedzieć na pytanie o zakres, zawsze używać <cflock scope="application"> (na przykład), ilekroć interakcja ze wspólnych zasobów.

2

Kontynuacja z czym @Mr. - powiedział Nate, używaj zamków, gdy obawiasz się warunków wyścigu. Na przykład możesz zablokować inicjowanie sesji, ale nie późniejsze odczyty. Podobnie możesz chcieć zablokować zapisy do zakresu aplikacji, ale nie możesz ich odczytać.

Zablokowanie odczytu jest dużo mniej przydatne od czasu CF6, w którym wprowadzono współdzielone zakresy bezpieczne dla wątków. W dawnych złych czasach, gdybyś nie był ostrożny, mógłbyś jednocześnie czytać i pisać ten sam adres pamięci. Ponieważ jednak CF stał się zasilany przez Javę, nie stanowi to problemu.

Nazwane zamki są użyteczne, jak zademonstrował, do blokowania wszystkiego, co nie ma takiego zakresu, jak zapis/odczyt pliku.

2

opierając się na innych sugestiach tutaj.

szczerze mówiąc, od czasu pojawienia się cf8 i teraz duplikat() może duplikować obiekty, używałbym tylko blokad zasięgu podczas zapisu do aplikacji, sesji lub zakresu serwera (btw, pisanie do zakresu serwera jest duże nie -nie w mojej książce).

jeśli chcesz odczytać dane, użyłbym duplicate() do zrobienia głębokiej kopii danych do zmiennej lokalnej i uniknięcia odczytu blokady razem. to zapobiegnie zakleszczeniom.

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

<cfset variables.firstname = duplicate(application.data.firstname)> 
1

Wielki czas, aby użyć nazwie blokujący jest, gdy masz „transakcja”, które chcesz, aby upewnić się dzieje, wszystko za jednym zamachem, na przykład aktualizowanego kilka tabel w bazie danych na raz, lub po prostu chcesz aby upewnić się, że dwóch użytkowników nie aktualizuje jednocześnie tego samego rekordu bazy danych lub podczas odczytu lub zapisu do pliku na serwerze, który może mieć więcej niż jednego użytkownika jednocześnie próbującego uzyskać do niego dostęp.

Mówiąc prościej, zawsze jest sytuacja, w której mogą wystąpić problemy, jeśli dwie prośby spróbują zrobić to samo w tym samym czasie, a następnie umieścić nazwany zamek wokół niego (lub jeśli ściśle wiąże się z sesją, aplikacją lub serwerem zakres, a następnie użyj zakresu).

Ben Nadel napisali wpisu blogu kiedyś, że powiedział:

„Tak jak ja to widzę, dwa warunki muszą być spełnione, aby wymagać wykorzystanie CFLock:

  1. udostępnionym dostęp do zasobu lub jego aktualizacja:
  2. Musi istnieć możliwość wystąpienia stanu wyścigowego, który spowoduje NEGATYWNY wynik. "

można nawet zagnieżdżać znaczniki CFLOCK, takie jak mają nazwie blokadę wokół transakcji i sesji lub aplikacji scoped zamki zagnieżdżone wewnątrz, ale zrobić to ostrożnie - jeśli robisz to źle, można mieć sytuacja "zakleszczenia", w której żadne żądanie nie może wykonać zablokowanej sekcji strony, a wszystkie żądania zablokowanej sekcji strony mogą zostać zablokowane do czasu przekroczenia limitu czasu. (Podręcznik ColdFusion opisuje najlepsze praktyki dla zagnieżdżonego blokowania.)

0

Jest to przykład z dokumentacji ColdFusion 8, która używa zmiennej strony do utworzenia "flagi lokalnej", którą można odczytać bez blokowania, aby sprawdzić, czy zmienne aplikacji mają został zainicjowany.

To, co się dzieje, to fakt, że musimy ustabilizować wyłączną blokadę, ponieważ uruchamianie jej za każdym razem, gdy strona zostanie załadowana, może powodować wąskie gardła, ponieważ blokada zabiera więcej czasu przetwarzania.

Nie wiem, czy pojawiły się lepsze techniki od tego czasu, ale sądzę, że i tak opublikuję to tutaj. Dokumenty ColdFusion często nie zapewniają dobrego kodu, więc chcę sprawdzić, czy ktoś może zobaczyć, jak można go ulepszyć.

  • mogę umieścić lokalną flagę w zakresie żądania tak, że jest ona dostępna nawet w niestandardowych znaczników itp Jednakże, jest to naprawdę potrzebne tylko w app.cfm, więc może to jest niepotrzebne.
  • Usunąłbym również isDefined() na rzecz structKeyExists(), aby nie musiał przechodzić przez wszystkie zakresy.
  • Do ustawiania zmiennych użyłbym również nawiasu nawiasowego, aby zachować wielkość liter (np.application ['myDsn'] = "zamówienia"). Ułatwia również wykrywanie zapisów zmiennych, które są nieco ważniejsze niż odczyty zmiennych. (Ten jest po prostu moje preferencje)

Źródło: 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>