2013-04-23 12 views
16

Ich habe den folgenden Code DB-Verbindung zu testen, sie in regelmäßigen Abständen für die DB die Verfügbarkeit zu prüfen läuft:Wie für Datenbank-Verfügbarkeit prüfen

private bool CheckDbConn() 
{ 
    SqlConnection conn = null; 
    bool result = true; 

    try 
    { 
     conn = DBConnection.getNewCon(); 
     ConnectionState conState = conn.State; 

     if (conState == ConnectionState.Closed || conState == ConnectionState.Broken) 
     { 
      logger.Warn(LogTopicEnum.Agent, "Connection failed in DB connection test on CheckDBConnection"); 
      return false; 
     }    
    } 
    catch (Exception ex) 
    { 
     logger.Warn(LogTopicEnum.Agent, "Error in DB connection test on CheckDBConnection", ex); 
     return false; // any error is considered as db connection error for now 
    } 
    finally 
    { 
     try 
     { 
     if (conn != null) 
     { 
      conn.Close(); 
     } 
     } 
     catch (Exception ex) 
     { 
     logger.Warn(LogTopicEnum.Agent, "Error closing connection on CheckDBConnection", ex); 
     result = false; 
     } 
    } 
    return result; 
} 

Und:

static public SqlConnection getNewCon() 
{ 
    SqlConnection newCon = new SqlConnection(); 
    newCon.ConnectionString = DBConnection.ConnectionString; // m_con.ConnectionString; 
    newCon.Open(); 
    return newCon; 
} 

Meine Frage ist: wird diese wie erwartet arbeiten?

Genauer gesagt, ich bin besorgt über den Test der ConnectionState. Ist es möglich, dass der Zustand wird: Verbindung (seit Open() ist synchron)?

Was soll ich in diesem Fall tun?

Vielen Dank im Voraus, Omer

Antwort

32

können Sie wie folgt versuchen.

public bool IsServerConnected() 
    { 
     using (var l_oConnection = new SqlConnection(DBConnection.ConnectionString)) 
     { 
      try 
      { 
       l_oConnection.Open(); 
       return true; 
      } 
      catch (SqlException) 
      { 
       return false; 
      } 
     } 
    } 
+0

was ist, wenn l_oConnection.Close(); Wird eine Ausnahme im finally Block werfen? –

+1

mit ... Schließen und entsorgen Sie die Verbindung, keine Notwendigkeit, dann zu schließen – Steve

+0

Ich habe dies verwendet, aber fand es wahr beim ersten Aufruf, nachdem die Datenbank offline genommen wurde. Dies war mit. Net 3.5 gegen einen SQL Server 2012 db. – monty

9

SqlConnection ein SqlException werfen, wenn es nicht mit dem Server verbinden kann.

public static class SqlExtensions 
{ 
    public static bool IsAvailable(this SqlConnection connection) 
    { 
     try 
     { 
      connection.Open(); 
      connection.Close(); 
     } 
     catch(SqlException) 
     { 
      return false; 
     } 

     return true; 
    } 
} 

Verbrauch:

using(SqlConnection connection = GetConnection()) 
{ 
    if(connection.IsAvailable()) 
    { 
     // Success 
    } 
} 
8

Ihr Code scheint in Ordnung, aber Sie müssen wirklich die IDisposable Muster verwenden, und einige Namenskonvention zu:

private bool CheckDbConnection(string connectionString) 
{ 
    try 
    { 
     using(var connection = new SqlConnection(connectionString)) 
     { 
      connection.Open(); 
      return true; 
     } 
    } 
    catch (Exception ex) 
    { 
     logger.Warn(LogTopicEnum.Agent, "Error in DB connection test on CheckDBConnection", ex); 
     return false; // any error is considered as db connection error for now 
    } 
} 

Und connection.Close() ist nicht anzunehmen werfen. Verwenden Sie einfach den using Block und Sie sind in Ordnung.

Keine Notwendigkeit, den Close Zustand zu testen, seit Sie es gerade geöffnet haben.
More about the Broken state:

Die Verbindung mit der Datenquelle Unterbrochene gebrochen ist. Dies kann nur auftreten, nachdem die Verbindung geöffnet wurde. Eine Verbindung in diesem Zustand kann geschlossen und dann wieder geöffnet werden. (Dieser Wert ist für zukünftige Versionen des Produkts reserviert.)

Also wirklich, keine Notwendigkeit, das zu testen.

Der Status Connecting konnte festgestellt werden, wenn Sie sich in einem Multithreadkontext befinden und Ihre Instanz der Verbindung freigegeben ist. Aber hier ist es nicht so.

0

Ich kann nicht so Kommentar ...

... vermeiden auch allgemeine Ausnahmen "catch (Exception ex)" Fang und versuchen bestimmte Ausnahmen, wie die Beispiele oben "catch (SqlException ex)" zu fangen

0

Tatsächlich hat die Verbindungsklasse im visuellen Studio eine Sonnenschutzeigenschaft.

Wenn sich der Verbindungsstatus ändert, wird das Verbindungsstatusereignis trigerred.

möchten Sie vielleicht diesen Artikel überprüfen.

https://msdn.microsoft.com/en-us/library/aa326268(v=vs.71).aspx

+0

Nicht sicher, wie es mit Visual Studio zusammenhängt, und wenn Sie sich den Post ansehen, hat er connectionState drin ... –

0

I @Ramesh Durai-Lösung wurde mit aber, dass auf meinem Setup mindestens (die App calling/Prüfung regelmäßig, nachdem die App gestartet hatte, mit .Net 3.5 mit SQL Server 2012-Datenbank) festgestellt, dass die ersten Anruf an IsConnected() nachdem die Datenbank offline genommen wurde true zurückgegeben. Es warf jedoch die erwartete Ausnahme auf die folgende Zeile:

public bool IsConnected() { 
    using (var conn = new SqlConnection(DBConnection.ConnectionString)) { 
     using (var cmd = New SqlCommand("SELECT 1", conn)) { 
      try { 
       conn.Open(); 
       cmd.ExecuteScalar(); 
       return true; 
      } catch (SqlException) { 
       return false; 
      } 
     } 
    } 
}