【问题标题】:How to check for database availability如何检查数据库可用性
【发布时间】:2013-04-16 18:34:02
【问题描述】:

我有以下代码来测试数据库连接,它会定期运行以测试数据库可用性:

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() 是同步的)?

这种情况我该怎么办?

【问题讨论】:

  • 我不能评论所以... ...也避免捕获一般异常“catch(Exception ex)”并尝试捕获特定异常,例如上面的示例“catch(SqlException ex)”

标签: c# .net sql sql-server connection


【解决方案1】:

你可以这样试试。

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

【讨论】:

  • 如果 l_oConnection.Close();会在 finally 块中抛出异常吗?
  • 使用...关闭并释放连接,无需关闭
  • 我正在使用它,但发现它在数据库脱机后的第一次调用中返回 true。这是针对 sql server 2012 db 使用 .Net 3.5。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    您的代码看起来不错,但您确实需要使用 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:

    Broken 与数据源的连接已断开。这可能发生 只有在打开连接之后。此状态下的连接 可能会关闭然后重新打开。 (这个值是为将来保留的 产品的版本。)

    真的,没必要测试。

    如果您在多线程上下文中并且您的连接实例是共享的,则Connecting 状态可能会被捕获。但这里不是你的情况。

    【讨论】:

      【解决方案4】:

      如果调用此代码,则不会阻塞 UI。

      public static class DatabaseExtensions
      {
          public static async Task<bool> IsConnectionViable(this string connectionStr)
          {
              await using var sqlConn = new SqlConnection(connectionStr);
              return await sqlConn.IsConnectionViable();
          }
      
          public static async Task<bool> IsConnectionViable(this SqlConnection connection)
          {
              var isConnected = false;
      
              try
              {
                  await connection.OpenAsync();
                  isConnected = (connection.State == ConnectionState.Open);
              }
              catch (Exception)
              {
                  // ignored
              }
      
              return isConnected;
          }
      }
      

      【讨论】:

        【解决方案5】:

        实际上,在 Visual Studio 中,连接类具有 sonnectionstate 属性。

        当连接状态改变时,会触发连接状态改变事件。

        您可能想查看这篇文章。

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

        【讨论】:

        • 不确定它与visual studio有什么关系,另外如果你看帖子,它里面有connectionState...
        【解决方案6】:

        我正在使用@Ramesh Durai 的解决方案,但发现至少在我的设置中(应用程序启动后定期调用/测试应用程序;使用带有 Sql Server 2012 数据库的 .Net 3.5)第一次调用 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;
                    }
                }
            }
        }
        

        【讨论】:

          【解决方案7】:

          此代码用于 Mysql。

          public class Program
          {
          string connection = "SERVER=localhost; user id=root; password=; database=dbname";
          private void Form1_Load(object sender, System.EventArgs e)
          {
          checkifconnected();
          }
          
          private void checkifconnected()
          {
          MySqlConnection connect = new MySqlConnection(connection);
          try{
          connect.Open();
          MessageBox.Show("Database connected");
          }
          catch
          {
          MessageBox.Show("you are not connected to database");
          }
          }
          
          public static void Main()
          {
          
          }
          }
          

          【讨论】:

            猜你喜欢
            • 2014-06-24
            • 1970-01-01
            • 2012-09-26
            • 2015-02-05
            • 2017-03-25
            • 1970-01-01
            • 1970-01-01
            • 2015-11-21
            • 1970-01-01
            相关资源
            最近更新 更多