2013-04-23 2 views
16

У меня есть следующий код, чтобы проверить DB соединение, она периодически запускается для проверки БД наличие:Как проверить наличие базы данных

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

И:

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

Мой вопрос: будет ли это работайте, как ожидалось?

В частности, я заинтересован в проверке ConnectionState. Возможно ли, что состояние будет: соединение (с Open() является синхронным)?

Что делать в этом случае?

Заранее спасибо, Омер

ответ

32

Вы можете попробовать вот так.

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

что делать, если l_oConnection.Close(); выкинет исключение в блок finally? –

+1

используя ... закрыть и удалить соединение, не нужно закрывать тогда – Steve

+0

Я использовал это, но нашел, что он вернётся при первом вызове после того, как база данных была отключена. Это использовало .Net 3.5 для SQL Server 2012 db. – monty

9

SqlConnection бросит SqlException, когда он не может подключиться к серверу.

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

     return true; 
    } 
} 

Использование:

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

Ваш код кажется, хорошо, но вам действительно нужно использовать IDisposable шаблона, и некоторое именование тоже:

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

И connection.Close() не предполагается бросить. Просто используйте блок using, и все в порядке.

Не нужно проверять состояние Close, так как вы только что открыли его.
More about the Broken state:

Сломанный Подключение к источнику данных нарушается. Это может произойти только после того, как соединение было открыто. Соединение в этом состоянии может быть закрыто, а затем снова открыто. (Это значение зарезервировано для будущих версий .)

Так что, действительно, нет необходимости проверять это.

Состояние Connecting может быть уловлено, если вы находитесь в многопоточном контексте, а ваш экземпляр соединения является общим. Но это не ваше дело.

0

Я не могу комментировать, так ...

... также избежать ловель общих исключений «поймать (Exception ех)» и попытаться поймать конкретные исключения, как в приведенных выше примерах «улова (SQLException бывшим)»

0

Фактически, в визуальной студии, класс связи имеет свойство sonnectionstate.

при изменении состояния соединения, связь statechange событие тригера.

вы можете проверить эту статью.

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

+0

Не уверен, как это связано с визуальной студией, плюс, если вы посмотрите на сообщение, в нем есть connectionState ... –

0

Я использовал решение @Ramesh Durai, но обнаружили, что на моей установке, по крайней мере (приложение вызова/тестирование периодически после того, как приложение начала, используя .NET 3.5 с Sql Server 2012 базы данных), что первая позвоните по телефону IsConnected() после того, как он забрал базу данных в автономном режиме, вернулся true. Однако он выбрасывал ожидаемое исключение по линии ExecuteScalar() ниже:

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; 
      } 
     } 
    } 
} 
Смежные вопросы