我應該在ColdFusion中使用範圍鎖定(應用程序,服務器等)還是命名鎖定?



Answers

繼續@Mr。 Nate說,只要你擔心競賽條件,就使用鎖。 例如,您可能想要鎖定會話初始化,但不是後續的讀取。 同樣,您可能想要將寫入鎖定到應用程序作用域,但不能讀取。

從CF6開始,鎖定讀取功能的用處就不大了,因為CF6引入了線程安全的共享變量作用域。 在過去不好的時候,如果你不小心,你可能會同時讀寫同一個內存地址。 但是,由於CF變成了Java,所以這不是問題。

正如他演示的,命名鎖是非常有用的,用於鎖定任何沒有作用域的東西,比如文件讀/寫。

Question

什麼時候適合使用<cflock scope =“application”>或者與<cflock name =“foo”>相反?

具體來說,我感興趣的是使用CFLock來保護應用程序,會話或服務器範圍內的共享對象,但是我也有興趣了解在ColdFusion中鎖定的不同用法。




使用命名鎖定的好時機是當你有一個“事務”時,你想確保一次完成,例如一次更新數據庫中的多個表,或者當你只是想確保兩個用戶都不是一次不更新同一數據庫記錄,或者在讀取或寫入服務器上的文件時,可能一次有多個用戶嘗試訪問該文件。

簡而言之,如果兩個請求試圖同時做同樣的事情,那麼任何時候都有可能出現問題的情況下,請在其周圍放置一個命名鎖(或者,如果嚴格涉及會話,應用程序或服務器範圍,則使用範圍鎖定)。

Ben Nadel曾經發表過一篇博客文章,他說:

“我看到它的方式,必須滿足兩個條件才能要求使用CFLock:

  1. 正在訪問或更新共享資源。
  2. 必須有可能導致負面結果的競賽狀況。“

你甚至可以嵌套CFLOCK標籤,比如在一個事務周圍有一個命名鎖,以及嵌套在會話或應用程序範圍內的鎖,但要小心 - 如果你做錯了,你可能會有一個“死鎖”的情況,沒有請求可以執行頁面的鎖定部分,並且可能會阻止對頁面鎖定部分的所有請求,直到出現超時。 (ColdFusion手冊介紹了嵌套鎖定的最佳實踐。)




這是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>





Related