2017-04-17 14 views
1

MySqlデータベースへの接続状態を検出したいと思います。私のデータベースは私のアプリケーションとは別のサーバーに配備されており、ネットワーク経由で接続を失う可能性があります。だから私はこのシナリオを考慮に入れなければならない。ここでMySqlへのハンドル接続が失われました

は(単純化した試験例)私がこれまで試したものです:

にIOException:

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への接続が失われた場合、私は一般的な例外を得書き込むことができません転送接続へのデータ: 確立された接続は、ホスト マシンのソフトウェアによって中断されました。

私は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; 
    } 
    } 

ような何かを行う可能性があるとします。あなたの欠陥が致命的であるかどうかは、テストなしでは伝えにくいです。

これらのConnectionインスタンスはで、スレッドセーフではありません。または任意の方法でリエントラントです。タイマーハンドラまたはスレッドで1つを使用する場合、のみがそのコンテキストで使用できます。それ以外の場合は、タイマーやスレッドが呼び出されたときに既に使用されている場合は、状況が悪化します。運が良ければ、例外が発生します。もしあなたが幸運でないなら、あなたの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

関連する問題