代码重复自身导致数据库中的重复记录

时间:2011-01-30 19:41:09

标签: c#

这个问题有点难以解释但是在这里。我有一个函数,可以从本地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;
            }
        }

问题出在if语句perform ==“insert”&& !recordFound。

我不确定上面的代码是否有助于解决问题,但这是从函数b调用时出错的函数,但是从函数A可以正常工作。感谢您提供的任何帮助和建议。

3 个答案:

答案 0 :(得分: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;
            }
        }
}

锁定将允许一次仅在线程上访问代码。所以不再重复。

答案 1 :(得分:2)

我给你的建议:

  • 始终使用交易,您将无法进行复制。您还可以使LoginName列唯一并正确处理db错误。
  • 请不要将字符串连接到构建查询。使用命令参数 - 最简单的方法逃避SQL注入。目前您至少有4个易受攻击的参数。太棒了;)

答案 2 :(得分:0)

我建议在cmd.ExecuteNonQuery();上设置一个断点并在每次点击时检查call stack,特别注意第二次/重复点击。还要注意which thread断点正在被击中。做这些事情应该指出你的问题。