簡體   English   中英

多線程環境中的mysql連接器

[英]mysql connector in a multi-threaded environment

我有一個連接到mysql服務器以獲取數據的ac#服務器。 這台c#服務器是游戲的后端服務器,它為當前登錄的每個玩家提供一個開放線程。我該如何進行mysql連接(每個線程的開放連接)? 對所有線程使用鎖定的單個連接?

我在某處讀到有一個“線程池”。 真的嗎? 如果是這樣,這是使用它的正確方法:

using(var conn = new MySqlConnection(DatabaseHelper.getConnectionString()))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT username FROM characters WHERE id=1";
    using (var reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            user = reader.GetString("username");
        }
    }
}

我認為您在這里混淆了兩種不同的資源; 您可能確實確實希望為每個已登錄的播放器打開一個線程(實際上是一個進程),但這並不意味着您應該一直為每個播放器打開與數據庫的連接,因為不管理數據庫連接,文件句柄等內容。資源,並且在完成使用后應立即釋放它們。

有C#的一個很好的介紹和說明線程在這里

您僅應在需要時打開與數據庫的連接。 這意味着您的數據訪問類可以多次實例化(這是最簡單的設計),每個類都有自己的連接。 如果您使用連接池 (我覺得您可能實際上一直在詢問),那么您將進一步受益。 轉向靜態數據庫連接設計(許多人共享相同的dao類)可能會遇到更多問題,因為您可能必須同步某些資源,確保某些變量只能通過鎖定或類似操作依次訪問,等等。

例如,您可以在此處閱讀有關此內容的更多信息。 微軟還談論連接池的好處在這里

上面的代碼是連接數據庫的一個很好的起點,其中包括要關閉的using語句,並在完成連接后立即處置該連接; 您可能還會考慮以下改進:

using(var conn = new MySqlConnection(DatabaseHelper.getConnectionString())) 
{
  using (var cmd = conn.CreateCommand()) 
  { 
      conn.Open(); 
      cmd.CommandType = CommandType.Text;
      //Parameterize your queries!
      cmd.CommandText = "SELECT username FROM characters WHERE id=?"; //Use ? as placeholder for parameters, and add parameters in the order they appear in your query.
      cmd.Parameters.Add(new MySqlParameter("@userid", MySqlDbType.Int, userid));

      using(IDataReader reader = cmd.ExecuteReader())
      { 
          //You should only expect one record. You might want to test for more than 1 record.
          if (reader.Read()) 
          { 
              user = reader.GetString(reader.GetOrdinal("username")); //Think also about null value checking.
          } 
      } 
  }
}

您可能有一個DAO類,或一個用戶類上的方法來執行此操作。 例如,如果它是用戶的一種方法,則可以執行以下操作:

User myUser = new User(7);
myUser.Load(); 

在Load內部,您可能會調用的方法之一是PopulateFromDB(),它將包含上面的代碼,並將加載該用戶的所有屬性。 您可能還具有執行相同操作的DAO類:

UserLoader loader = new UserLoader();
string userName = loader.GetUserName(int userId);

它將使用上面示例中的代碼返回用戶名。 我希望此方法位於像User這樣的類上,因為它在邏輯上與之相連。 但是,您將冒着將DAO邏輯與用戶業務邏輯混合在一起的風險,這本身就是一個話題。

與其編寫大量這種數據訪問邏輯,不如考慮使用某種形式的框架,例如ORM或類似的框架- 已經針對SO上的MySql回答了這個問題 這也可以節省大量時間和精力,並使您可以專注於設計。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM