2013-04-23 7 views
16

Ho il seguente codice per verificare la connessione DB, viene eseguito periodicamente per verificare DB disponibilità:Come controllare la disponibilità del database

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

E:

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

la mia domanda è: sarà questo funziona come previsto?

In particolare, sono interessato aobut il test dello ConnectionState. È possibile che lo stato sia: connessione (dal momento che Open() è sincrono)?

Cosa devo fare in questo caso?

Grazie in anticipo, Omer

risposta

32

Si può provare in questo modo.

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

cosa succede se l_oConnection.Close(); getterà un'eccezione nel blocco finale? –

+1

usando ... chiudi e getta la connessione, non è necessario chiudere quindi – Steve

+0

Io stavo usando questo, ma ho trovato restituito true alla prima chiamata dopo che il database è stato portato offline. Questo stava usando .Net 3.5 contro un db sql server 2012. – monty

9

SqlConnection lancerà una SqlException quando non può connettersi al server.

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

     return true; 
    } 
} 

Usage:

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

Il tuo codice sembra in ordine, ma si ha realmente bisogno di utilizzare il modello di IDisposable, e alcuni convenzione di denominazione troppo:

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 
    } 
} 

E connection.Close() non dovrebbe gettare. Basta usare il blocco using e stai bene.

Non è necessario testare lo stato Close, poiché è stato appena aperto.
More about the Broken state:

rotto il collegamento alla sorgente dati è rotto. Questo può verificarsi solo dopo l'apertura della connessione. Una connessione in questo stato potrebbe essere chiusa e quindi riaperta. (Questo valore è riservato per future versioni del prodotto.)

Quindi, in realtà, non c'è bisogno di testare questo.

Lo stato Connecting potrebbe essere catturato se ci si trova in un contesto multithread e l'istanza di connessione è condivisa. Ma non è il tuo caso qui.

0

non posso commentare in modo ...

... anche evitare la cattura di eccezioni generali "catch (Exception ex)" e cercare di intercettare le eccezioni specifiche come gli esempi sopra "catch (SqlException ex)"

0

in realtà, in studio visivo, la classe di connessione ha la proprietà sonnectionstate.

quando lo stato della connessione cambia, l'evento di connessione statechange è stato attivato.

potresti voler controllare questo articolo.

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

+0

Non sei sicuro di come sia correlato allo studio visivo, in più se guardi il post, ha connectionState in esso ... –

0

stavo usando la soluzione di @Ramesh Durai ma ho trovato che il mio setup almeno (l'applicazione di chiamata/test periodicamente dopo l'applicazione aveva iniziato, utilizzando Net 3.5 con SQL Server 2012 database) che il primo Chiamare a IsConnected() dopo aver preso il database offline stava restituendo true. Tuttavia, si stava gettando l'eccezione prevista sulla linea ExecuteScalar() di seguito:

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; 
      } 
     } 
    } 
} 
Problemi correlati