2017-04-17 115 views
1

我想檢測連接狀態到MySql數據庫。我的數據庫部署在與我的應用程序不同的服務器上,並且很有可能通過網絡失去與它的連接。所以我必須考慮這種情況。處理連接到MySql丟失

這裏是我試過到目前爲止(簡化的測試爲例):

static string connectionString = "***"; 
public static MySqlConnection Connection; 
static System.Timers.Timer _timer; 

static void _timer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    try 
    { 
     if (Connection.State != System.Data.ConnectionState.Open) 
      Connection.Open(); 
     // Call method to invoke MySqlCommand.ExecuteNonQuery 
     mysqlCommand.ExecuteNonQuery(); 
    } 
    catch (MySqlException ex) 
    { 
     Console.WriteLine("SQL EXCEPTION: " + ex); 
     // Handle all type of database exceptions 
     switch(ex.Number) 
     {...} 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine("OTHER EXCEPTION: " + ex); 
    } 
} 

static void Main(string[] args) 
{ 
    Connection = new MySqlConnection(connectionString); 

    _timer = new System.Timers.Timer(3000); 
    _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed); 
    _timer.Enabled = true; 

    Console.ReadKey(); 
} 

如果到MySql的連接丟失,我有一種普遍的例外:

IOException異常:無法寫入數據傳輸到傳輸連接: 建立的連接被主機 機器中的軟件中止。

我期待MySqlException被解僱,但事實並非如此。 此外,如果與MySql的連接恢復,我仍然可以獲得IOException而不是執行查詢。似乎,MySqlConnection對象尚未更新,它不關心新的連接狀態。

  1. 什麼是處理連接丟失異常的最佳方法?
  2. 如何在連接恢復時刷新MySqlConnection

注:,我不能實例爲每個新查詢的新MySqlConnection對象,因爲我想改變程序具有隻初始化一次MySqlConnection類型的辛格爾頓。我知道這是一個糟糕的設計,但我現在不想改變這種設計。我只想抓住連接丟失的異常並嘗試刷新MySqlConnection以繼續正常工作。

回答

0

如果您的MySqlConnection實例失去了與您的MySQL服務器的連接,則不能指望自動或以其他方式恢復實例的連接。

您需要嘗試重新連接MySqlConnection的新實例。丟失連接的端口現在處於終端狀態,不能重新使用。

要做到這一點,我想你可以做這樣的事情

... 
    catch (MySqlException ex) 
    { 
    if (/*ex is a connection drop */) { 
     Connection?.Dispose(); 
     Connection = new MySqlConnection(...); 
     Connection.ConnectionString = /* your connection string */; 
     Connection.Open(); 
    } 
    else { 
     throw; 
    } 
    } 

你是正確的,你的設計有缺陷。沒有測試,你的缺陷是否是致命的是很難說的。

這些連接實例是非線程安全或以任何方式重入。如果在定時器處理程序或線程中使用一個,則可能只有在該上下文中使用它。否則,如果在您的計時器或線程被調用時它已經在使用中,事情會變得非常危險。如果你幸運的話,你會得到一個例外。如果你不那麼幸運,你的MySQL服務器會收到客戶端的亂碼並檢測到它。如果你不那麼幸運,你的數據會被炒得沸沸揚揚。

ADO.NET和MySqlConnection object implement connection pooling。這很重要,因爲它會打開連接,使用它們,然後關閉它們,比您預期的便宜很多。

有時MySQL會丟失程序長時間處於打開狀態的連接。如果這是你的問題,這篇文章可能會有幫助。 How can I change the default Mysql connection timeout when connecting through python?

+0

所以我唯一的選擇是改變我的設計,併爲每個數據庫交互創建新的MySqlConnection實例? – Mhd