2011-12-10 64 views
0

我有一個連接到mysql服務器的c#服務器以獲取數據。這個c#服務器是一個遊戲的後端服務器,對於當前登錄的每個玩家都有一個開放的線程。我該如何去做mysql連接,每個線程都打開一個連接?一個連接使用鎖定所有線程?多線程環境下的mysql連接器

我在某處看到有一個'threadpool'。真的嗎?如果是這樣,這是使用它的正確方法:

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"); 
     } 
    } 
} 

回答

4

我認爲你在這裏混淆了兩種不同的資源;您可能確實需要爲每個登錄的玩家開放一個線程(實際上是一個進程),但這並不意味着您應該連接到每個玩家不斷開放的數據庫,因爲數據庫連接,文件句柄等操作不受管理資源,只要你完成它們就應該儘快解脫。

有一個很好的介紹和C#線程說明here

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

例如,您可以閱讀更多關於此here的信息。微軟還談到了連接池here的好處。

上面的代碼是連接數據庫的一個很好的起點,通過包含正在關閉的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(); 

內側載荷的,你可以調用的方法之一是PopulateFromDB(),這將包含上面的代碼,並且將加載所有該用戶的屬性。您可能也有一個DAO類可以做同樣的事情:

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

這將使用上面的示例中的代碼返回用戶名。我更喜歡這種方法在像User這樣的類上,因爲它在邏輯上連接到它。但是,您將冒着將DAO邏輯與用戶業務邏輯混合在一起的風險,這是一個獨立的主題。

您可能會考慮查看某種形式的框架,比如ORM或類似的框架 - SO question has already been answered for MySql,而不是寫很多這種數據訪問邏輯。這也可以爲您節省大量的時間和精力,並且可以讓您專注於設計。

+0

所以,至少在短文中,上面的例子應該是我正在使用的? – will

+0

@是的,最重要的兩個方面是USING語句,這意味着一旦你完成了unmanged資源就會被釋放,並且SQL查詢參數將從sql注入中爲你的應用程序添加一層保護。我會在答案的底部添加一些關於如何在實踐中使用它的例子。 – dash

+0

查詢的參數化對許多數據庫系統也有好處,因爲它們也可以爲參數化查詢重用查詢執行計劃。 – dash