2013-01-03 114 views
0

我正在C#中運行一個循環,它讀取一個文件並在Windows 8 64位環境中使用MySQL ODBC 5.1驅動程序更新MySQL數據庫。MySQL OdbcCommand命令somtimes掛起?

的操作是簡單

  1. 計數+1
  2. 參見如果文件存在
  3. 裝載XML文件(的XDocument)
  4. 從的XDocument獲取數據
  5. 打開ODBCConnection
  6. 運行一個針對MySQL數據庫存儲數據的一對存儲過程
  7. 關閉ODBCConnection

問題是,一段時間後,它將掛起例如一個OdbcCommand.ExecuteNonQuery。它並不總是一樣的SP,它會掛在?

這是一個真正的問題,我需要循環60 000個文件,但它一次只能保存大約1000個文件。

編輯1: seemse到accure這裏赫弗時間的問題:

public bool addPublisherToGame(int inPublisherId, int inGameId) 
     { 
      string sqlStr; 
      OdbcCommand commandObj; 
      try 
      { 
       sqlStr = "INSERT INTO games_publisher_binder (gameId, publisherId) VALUE(?,?)"; 

       commandObj = new OdbcCommand(sqlStr, mainConnection); 
       commandObj.Parameters.Add("@gameId", OdbcType.Int).Value = inGameId; 
       commandObj.Parameters.Add("@publisherId", OdbcType.Int).Value = inPublisherId; 

       if (Convert.ToInt32(executeNonQuery(commandObj)) > 0) 
        return true; 
       else 
        return false; 

      } 
      catch (Exception ex) 
      { 
       throw (loggErrorMessage(this.ToString(), "addPublisherToGame", ex, -1, "", "")); 
      } 
      finally 
      { 

      } 
     } 


protected object executeNonQuery(OdbcCommand inCommandObj) 
     { 
      try 
      { 
       //FileStream file = new FileStream("d:\\test.txt", FileMode.Append, FileAccess.Write); 

       //System.IO.StreamWriter stream = new System.IO.StreamWriter(file); 
       //stream.WriteLine(DateTime.Now.ToString() + " - " + inCommandObj.CommandText); 
       //stream.Close(); 
       //file.Close(); 

       //mainConnection.Open(); 
       return inCommandObj.ExecuteNonQuery(); 
      } 
      catch (Exception ex) 
      { 
       throw (ex); 
      } 
     } 

我可以看到,在參數是否正確

打開和關閉連接的是一頂方法完成永遠循環(終於)。

編輯2:

這是將提取信息,並保存到數據庫的方法:

public Boolean addBoardgameToDatabase(XElement boardgame, GameFactory gameFactory) 
     { 
      int incomingGameId = -1; 
      XElement tmpElement; 
      string primaryName = string.Empty; 
      List<string> names = new List<string>(); 
      GameStorage externalGameStorage; 

      int retry = 3; 
      try 
      { 
       if (boardgame.FirstAttribute != null && 
        boardgame.FirstAttribute.Value != null) 
       { 
        while (retry > -1) 
        { 
         try 
         { 
          incomingGameId = int.Parse(boardgame.FirstAttribute.Value); 

          #region Find primary name 
          tmpElement = boardgame.Elements("name").Where(c => c.Attribute("primary") != null).FirstOrDefault(a => a.Attribute("primary").Value.Equals("true")); 

          if (tmpElement != null) 
           primaryName = tmpElement.Value; 
          else 
           return false; 
          #endregion 

          externalGameStorage = new GameStorage(incomingGameId, 
                   primaryName, 
                   string.Empty, 
                   getDateTime("1/1/" + boardgame.Element("yearpublished").Value), 
                   getInteger(boardgame.Element("minplayers").Value), 
                   getInteger(boardgame.Element("maxplayers").Value), 
                   boardgame.Element("playingtime").Value, 
                   0, 0, false); 

          gameFactory.updateGame(externalGameStorage); 
          gameFactory.updateGameGrade(incomingGameId); 

          gameFactory.removeDesignersFromGame(externalGameStorage.id); 
          foreach (XElement designer in boardgame.Elements("boardgamedesigner")) 
          { 
           gameFactory.updateDesigner(int.Parse(designer.FirstAttribute.Value), designer.Value); 
           gameFactory.addDesignerToGame(int.Parse(designer.FirstAttribute.Value), externalGameStorage.id); 
          } 

          gameFactory.removePublishersFromGame(externalGameStorage.id); 
          foreach (XElement publisher in boardgame.Elements("boardgamepublisher")) 
          { 
           gameFactory.updatePublisher(int.Parse(publisher.FirstAttribute.Value), publisher.Value, string.Empty); 
           gameFactory.addPublisherToGame(int.Parse(publisher.FirstAttribute.Value), externalGameStorage.id); 
          } 

          foreach (XElement element in boardgame.Elements("name").Where(c => c.Attribute("primary") == null)) 
           names.Add(element.Value); 

          gameFactory.removeGameNames(incomingGameId); 

          foreach (string name in names) 
           if (name != null && name.Length > 0) 
            gameFactory.addGameName(incomingGameId, name); 

          return true; 
         } 
         catch (Exception) 
         { 

          retry--; 
          if (retry < 0) 
           return false; 
         } 
        } 

       } 

       return false; 
      } 
      catch (Exception ex) 
      { 
       throw (new Exception(this.ToString() + ".addBoardgameToDatabase : " + ex.Message, ex)); 
      } 
     } 

然後我們得到了高一個臺階,將觸發addBoardgameToDatabase方法:

private void StartThreadToHandleXmlFile(int gameId) 
     { 
      FileInfo fileInfo; 
      XDocument xmlDoc; 
      Boolean gameAdded = false; 
      GameFactory gameFactory = new GameFactory(); 

      try 
      { 
       fileInfo = new FileInfo(_directory + "\\" + gameId.ToString() + ".xml"); 

       if (fileInfo.Exists) 
       { 
        xmlDoc = XDocument.Load(fileInfo.FullName); 

        if (addBoardgameToDatabase(xmlDoc.Element("boardgames").Element("boardgame"), gameFactory)) 
        { 
         gameAdded = true; 
         fileInfo.Delete(); 
        } 
        else 
         return; 
       } 

       if (!gameAdded) 
       { 
        gameFactory.InactivateGame(gameId); 
        fileInfo.Delete(); 
       } 
      } 
      catch (Exception) 
      { throw; } 
      finally 
      { 
       if(gameFactory != null) 
        gameFactory.CloseConnection(); 
      } 
     } 

然後終於頂級:

public void UpdateGames(string directory) 
{ 
    DirectoryInfo dirInfo; 
    FileInfo fileInfo; 
    Thread thread; 

    int gameIdToStartOn = 1; 

    dirInfo = new DirectoryInfo(directory); 
    if(dirInfo.Exists) 
    { 
     _directory = directory; 
     fileInfo = dirInfo.GetFiles("*.xml").OrderBy(c=> int.Parse(c.Name.Replace(".xml",""))).FirstOrDefault(); 

     gameIdToStartOn = int.Parse(fileInfo.Name.Replace(".xml", "")); 

     for (int gameId = gameIdToStartOn; gameId < 500000; gameId++) 
     { 
      try 
      { StartThreadToHandleXmlFile(gameId); } 
      catch(Exception){} 
     } 
    } 
} 
+0

我們能否看到該代碼? :) – Pacane

+2

我懷疑你沒有正確地關閉命令。對命令和連接使用'using'語句。 –

+0

我已經更新了一些代碼。 – Ivy

回答

0
  1. 通過向連接字符串添加「Pooling = true」來使用SQL連接池。
  2. 確保您正確關閉連接和文件。
  3. 您可以創建一個大型查詢並只執行一次,我認爲它比60.000鬆散查詢快得多!

你能展示一下你的代碼嗎?

+0

謝謝!我正在嘗試Pooling,希望它能解決問題。我正在打開和關閉(最後),因爲它應該是。我認爲數據庫調用可能會聚集在一起,但我不知道如何?有沒有一個聰明的工具可以將所有命令保存到腳本文件中,而不是在數據庫上運行它? – Ivy

+0

聯合並沒有解決問題。但是我已經更新了我的帖子,其代碼似乎僅限於此。 – Ivy