如何检查数据库可用性
我有以下代码来测试数据库连接,它会定期运行以测试数据库可用性:
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()
是同步的)?
在那种情况下我该怎么办?
提前谢谢,奥梅尔
你可以这样试试。
public bool IsServerConnected() { using (var l_oConnection = new SqlConnection(DBConnection.ConnectionString)) { try { l_oConnection.Open(); return true; } catch (SqlException) { return false; } } }
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 } }
你的代码似乎很好,但你真的需要使用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
状态。
关于Broken
状态的更多信息:
已断开与数据源的连接已断开。 只有在打开连接后才会发生这种情况。 可以关闭此状态下的连接,然后重新打开。 (此值保留给产品的未来版本。)
所以真的,没必要测试。
如果您处于multithreading上下文并且共享连接实例,则可以捕获Connecting
状态。 但这不是你的情况。
我不能这样评论……
…也避免捕获常规exception“catch(Exception ex)”并尝试捕获特定exception,如上面的示例“catch(SqlException ex)”
实际上,在visual studio中,连接类具有sonnectionstate属性。
当连接状态发生变化时,连接状态变化事件被触发。
你可能想查看这篇文章。
https://msdn.microsoft.com/en-us/library/aa326268(v=vs.71).aspx
我正在使用@Ramesh Durai的解决方案,但发现我的设置至少(应用程序启动后定期调用/测试;使用带有Sql Server 2012数据库的.Net 3.5 IsConnected()
在获取数据库后第一次调用IsConnected()
离线返回true
。 但是,它在下面的ExecuteScalar()
行中抛出了预期的exception:
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; } } } }