0

我有一個ColdFusion 8的問題,我發佈堆棧溢出不久前Coldfusion 8 doing both CFIf and the CFElse statement ,我認爲我已經縮小到一個MySQL問題,但(進一步調查),但我已經收窄它下降到多線程/每個會話的多個請求問題。 (這仍然可能是一個MYSQL的問題,但我不知道如何解決它)Coldfusion 8多線程併發

什麼是真正的代碼腳麻:

<cfif isValid("email", form.email)>  
    <cfquery name="check_user" datasource="#request.dsn#"> 
     SELECT var_username, var_password 
     FROM tbl_users 
     WHERE var_username = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.EMAIL#"> 
     AND var_password = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.PASSWORD#"> 
     </cfquery> 
    <cfif check_user.recordcount EQ 0> 
     <cfquery datasource="#request.dsn#" name="insertuser"> 
      INSERT INTO tbl_users (var_username, var_password)    VALUES 
      (<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.EMAIL#">,    <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.PASSWORD#">) 
     </cfquery> 
      <cflogin idletimeout="1800"> 
     <cfloginuser 
        name = "#FORM.email#" 
       password ="#FORM.password#" 
       roles = "0"> 
      </cflogin> 
     <cflocation addtoken="No" url="#request.secure_url#checkout.cfm"> 
    <cfelse> 
     <cfset client.error_message = "Your Email Address is already registered."> 
     <cflocation addtoken="No" url="#request.site_url#New-Account.html"> 
    </cfif> 
    <cfelse> 
    <cfset client.error_message = "Your Email Address is not Valid."> 
    <cflocation addtoken="No" url="#request.site_url#New-Account.html"> 
    </cfif> 

是存在由正在取得2個併發請求同一個用戶。如果請求稍微交錯,請求A將把用戶插入到數據庫中,但在請求A可以CFLOGINCFLOCATION之前,請求B獲取CFIF通知數據庫中已經存在用戶,並創建CLIENT.ERROR_MESSAGECFLOCATION' s到New-Account.html。 但是,如果請求不交錯,會發生什麼情況是代碼似乎有效,並將用戶發送到checkout.cfm頁面,但是在數據庫中,用戶會插入兩次。

我已經採取措施來嘗試解決此步驟:

1:同MySQL服務器中使用不同的數據庫(通過改變數據源到我們具有相似/相同tbl_users其他網站之一)。相同的結果。

2:把網站放在不同的coldfusion 8/windows 2003服務器(但使用相同的MYSQL服務器)。相同的結果。

3:將一個

<cflock name="NewUser" timeout="30" type="EXCLUSIVE"> 

在代碼的開頭和

</cflock> 

在碼的末尾。同樣的結果。

我真的認爲把CFLOCK放在代碼上可以解決這個問題,但它沒有,現在我不知道下一步該怎麼做(但可能是因爲我以前從未使用過CFLOCK,使用它錯誤)。有沒有人有任何想法如何解決這個問題,以便只發送一個請求?或者爲什麼2個請求正在發送的任何想法? (我不認爲它的pebkac,因爲我是一個做測試的人,而且我沒有按兩次提交按鈕)

另外,我使用的是Windows 2003的web服務器,帶有coldfusion 8.還有一個單獨的Windows 2003服務器與MySQL 5

回答

0

對不起我的等級不夠高,只是張貼您的問題在下面留言...

我不知道爲什麼你得到兩個或多個併發請求用戶代碼的這一部分。您是否正在使用AJAX或ColdFusion AJAX功能訪問其他CFM文件?

我認爲你的解決方案將是追蹤爲什麼一個用戶會多次擊中該部分代碼。

您可以使用<cflog>來跟蹤如何調用這段代碼。

+0

我不使用Coldfusion在本網站上提供的任何Ajax函數。我跑cflog,就像我說的,每個條目都有一個雙重條目,這裏是一個樣本,它有電子郵件和密碼試圖添加 - 「信息」,「jrpp-632」,「03/28/12「,」10:32:50「,」User [email protected] password「,」Information「,」jrpp-630「,」03/28/12「,」10:32:50「,, 「用戶[email protected]密碼」' – 2012-03-28 14:34:22

+0

很好的使用cflog。我假設你有一個用戶完成一次的登錄表單,並單擊提交按鈕登錄。現在我想到了,我的項目中有一個類似的問題。這是與IE。 IE允許用戶通過垃圾郵件點擊提交按鈕,每次點擊時,表單操作都會被調用。我的解決方案是放入一個小的JavaScript代碼片段,以便在點擊按鈕時禁用/隱藏按鈕。這可能是這種情況嗎? – 2012-03-28 19:52:34

+0

不,因爲我是進行測試並遇到問題的人,而且我沒有多次觸碰提交按鈕。 (但是,這將是一個好主意,當我把代碼生效時執行) – 2012-03-29 14:24:03

0

您正在構建一個併發應用程序。很高興你在開發週期中儘早發現這個問題。當併發應用程序使用DBMS約束來管理它們的併發而不是您在示例中顯示的那種代碼時,它們的工作效果最佳。

我建議你切換到InnoDB如果你還沒有使用它,然後設置你的tbl_users.var_username列作爲一個主鍵,在數據庫中有一個唯一的約束。

然後,從您的表中不要SELECT。只需要做INSERT。如果用戶名已經存在,您將從<cfquery>插入操作中得到例外。適當處理它。如果INSERT正常工作,則只需添加一個新用戶即可。如果失敗,您嘗試添加重複的用戶,並且您可以在Web用戶界面上呈現適當的響應。

+0

我正在使用InnoDB,並且我決定嘗試你的方法,所以我在數據庫中創建了var_username一個PK,並讓代碼執行INSERT,但是,它只是添加了另一個條目,無論用戶是否具有該用戶名。 (這可能是因爲我已經爲該表添加了另一個PK,它是一個Unique Auto Increase ID)。我不知道是否在桌上有兩個PK會導致這種情況,但它不起作用。 – 2012-04-02 15:23:24

+0

沒關係,沒有正確應用SQLyog中的唯一密鑰,現在我已經做了,它不再添加2個條目,但是現在看起來似乎存在使用此解決方案的其他一系列問題。我寧願不用這種方法來解決這個問題,而是找到併發的根本原因並解決這個問題。 (但是,感謝您使用獨特/插入方法,我將來可能會使用它,只要我解決這些問題) – 2012-04-02 15:50:44