2011-01-30 37 views
0

這個問題有點難以解釋,但是在這裏。我有一個從本地SQLiteDatabase在線添加記錄到MySQL數據庫的函數。首先調用一個函數來檢索本地數據,並將每行發送到上載函數,該函數將記錄添加到在線MySQL數據庫中。當從另一個函數A調用這些函數時,它可以很好地工作,但是從不同的函數調用時。函數B重複記錄被輸入到數據庫中。重複自身導致數據庫中重複記錄的代碼

在調試過程中嘗試解決問題時,我發現當它複製記錄時,它將轉到cmd.executeNonQuery(),然後轉到下一行,但無緣無故將返回到cmd.executeNonQuery ()因此重複記錄。代碼如下

private void uploadDatabase(string company, string oldCompany, string companyURL, string loginUsername, string oldUsername, string password, string type, string perform, string direction) 
     { 
      Boolean recordFound = false; 
      recordFound = checkRecordNotExist(company, loginUsername); 
      MySQLDBWork dbase = new MySQLDBWork(); 
      try 
      { 
       dbase.openConnection(); 
       if (perform == "insert" && !recordFound) 
       { 
        string query = "INSERT INTO `" + username + "` (pas_company, pas_companyURL, pas_username, pas_password, pas_type) " 
         + "VALUES ('" + company + "', '" + companyURL + "', '" + loginUsername + "', '" + password + "', '" + type + "')"; 
        Console.WriteLine("Query: " + query); 
        MySqlCommand cmd = new MySqlCommand(query, dbase.conn); 
        cmd.ExecuteNonQuery(); 
        recordFound = true; 
        query = ""; 
        company = ""; 
        loginUsername = ""; 
        cmd.Dispose(); 
       } 
       if (perform == "delete") 
       { 
        string query = "DELETE FROM `" + username + "` WHERE pas_company='" + company + "' AND pas_username='" + loginUsername + "'"; 
        dbase.performQuery(query); 
       } 
      } 
      catch (MySqlException ex) 
      { 
       Console.WriteLine("Adding Online Error: " + ex.Message); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("General Exception: " + ex.Message); 
      } 
      finally 
      { 
       dbase.closeConnection(); 
       //dbase.conn.Dispose(); 
       company = null; 
       loginUsername = null; 
      } 
     } 

的問題是,如果語句中執行==「插入」 & &!recordFound。

我不確定上面的代碼是否有助於解決問題,但這是從函數b調用時出錯的函數,但在函數A中正常工作。感謝您提供的任何幫助和建議。

+0

你確定你是(1)使用最新的源代碼(也許,重建會有幫助),和(2)調試調試,而不是你的應用程序的發佈版本? – Vlad 2011-01-30 19:50:21

回答

3

然後將在接下來的幾個行 ,但隨後沒有理由會漲回去 到cmd.executeNonQuery()

這聽起來像一個簡單的多線程問題。該函數再次從另一個線程訪問。所以發生的事情是,它在兩個線程中都存在於兩個線程中,然後插入到兩個線程中。

因此,創建一個鎖,並鎖定代碼......是這樣的:

private System.Object uploadLock = new System.Object(); 

private void uploadDatabase(string company, string oldCompany, string companyURL, string loginUsername, string oldUsername, string password, string type, string perform, string direction) 
     { 
      lock(uploadLock) { 
      Boolean recordFound = false; 
      recordFound = checkRecordNotExist(company, loginUsername); 
      MySQLDBWork dbase = new MySQLDBWork(); 
      try 
      { 
       dbase.openConnection(); 
       if (perform == "insert" && !recordFound) 
       { 
        string query = "INSERT INTO `" + username + "` (pas_company, pas_companyURL, pas_username, pas_password, pas_type) " 
         + "VALUES ('" + company + "', '" + companyURL + "', '" + loginUsername + "', '" + password + "', '" + type + "')"; 
        Console.WriteLine("Query: " + query); 
        MySqlCommand cmd = new MySqlCommand(query, dbase.conn); 
        cmd.ExecuteNonQuery(); 
        recordFound = true; 
        query = ""; 
        company = ""; 
        loginUsername = ""; 
        cmd.Dispose(); 
       } 
       if (perform == "delete") 
       { 
        string query = "DELETE FROM `" + username + "` WHERE pas_company='" + company + "' AND pas_username='" + loginUsername + "'"; 
        dbase.performQuery(query); 
       } 
      } 
      catch (MySqlException ex) 
      { 
       Console.WriteLine("Adding Online Error: " + ex.Message); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("General Exception: " + ex.Message); 
      } 
      finally 
      { 
       dbase.closeConnection(); 
       //dbase.conn.Dispose(); 
       company = null; 
       loginUsername = null; 
      } 
     } 
} 

鎖定將允許訪問代碼僅在線程的時間。所以沒有更多的重複。

0

我建議在cmd.ExecuteNonQuery();上設置一個斷點,並在每次擊中時檢查call stack,特別注意第二個/重複命中。還要注意which thread的斷點正在被打上。做這些事情應該指出你的問題。

2

我給你的建議:

  • 總是使用事務,你將無法做重複。您還可以使LoginName列唯一併正確處理數據庫錯誤。
  • 請勿連接字符串以建立查詢。使用命令參數 - 最簡單的方法轉義SQL注入。目前您至少有4個易受攻擊的參數。真的;)