0

也许这不是我写过的最好的源代码,但它是一个简单的表单,其目标是远程写入数据。我有两个 MySQLConnections 都用于本地数据库。localconnection 用于读取数据库并 updateconnection 编辑每一行。问题是,当我尝试更新数据库时,程序会引发超时并崩溃。我认为问题是由while 循环产生的。我的目的是读取一行,将其发布到服务器上,如果服务器返回的状态等于 200,则更新它。

这是代码,它在 updateConnection.ExcecuteNonQuery(); 上失败了

    // Local Database here.
    localCommand.Parameters.Clear();
    // 0 - Grab unsent emails
    string receivedMessages = "SELECT * FROM EMAIL WHERE HASSENT = 0";
    // Update connection init START
    string updateConnectionString = "Server=" + this.localServer + ";Database=" + this.localDatabase + ";Uid=" + this.localUser + ";Pwd=" + this.localpassword;
    MySqlConnection updateConnection = new MySqlConnection(updateConnectionString);
    updateConnection.Open();
    MySqlTransaction transaction = updateConnection.BeginTransaction();
    MySqlCommand updateCommand = new MySqlCommand();
    // Update connection init END
    localCommand.Connection = localConnection;
    localCommand.Prepare();
    try
    {
      localCommand.CommandText = receivedMessages;
      MySqlDataReader reader = localCommand.ExecuteReader();
      while (reader.Read()) // Local db read
      {
       String EID = reader.GetString(0);
       String message = reader.GetString(3);
       String fromEmail = reader.GetString(6);
       String toEmail= reader.GetString(12);
       // 1 - Post Request via HttpWebRequest
       var receivedResponse = JObject.Parse(toSend.setIsReceived(fromEmail, message, toEmail));
       // 2 - Read the JSON response from the server
       if ((int)receivedResponse["status"] == 200)
       {
           string updateInbox = "UPDATE EMAIL SET HASSENT = 1 WHERE EMAILID = @EID";
           MySqlParameter EMAILID = new MySqlParameter("@EID", MySqlDbType.String);
           EMAILID.Value = EID; // We use the same fetched above
           updateCommand.Connection = updateConnection;
           updateCommand.Parameters.Add(IID_value);
           updateCommand.Prepare();
           updateCommand.CommandText = updateInbox;
           updateCommand.ExecuteNonQuery();
       }
       else
       {
          // Notice the error....
       }
     }
   }
   catch (MySqlException ex)
   {
     transaction.Rollback();
     // Notice...

   }
   finally
   {
     updateConnection.Close();
   }
4

1 回答 1

1

如果不做一些实验,很难确切地说出这里出了什么问题。

不过有两种可能。

首先,您的程序似乎在 Web 服务器上运行,这必然会限制它运行有限的时间。但是,您遍历一个可能很大的结果集,并为该结果集中的每个项目执行持续时间无法控制的事情。

其次,您从 MySQL 服务器逐行读取结果集,并使用不同的连接尝试更新该结果集后面的表。这可能会导致死锁,其中 MySQL 服务器会阻止您的更新查询之一,直到选择查询完成,从而阻止选择查询的完成。

这个要怎么治?首先,尝试在此代码的每次调用中处理固定且少量的行。将您的选择查询更改为

SELECT * FROM EMAIL WHERE HASSENT = 0 LIMIT 10

并且您每次将处理 10 条记录。

其次,从选择查询中读入整个结果集,进入数据结构,然后遍历项目。换句话说,不要在选择中嵌套更新。

第三,通过更改SELECT *为减少您处理的数据量SELECT field, field, field

于 2013-06-17T18:27:09.780 回答