DB接続をテストする次のコードがあり、定期的に実行して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()
は同期しているため)
その場合はどうすればよいですか?
事前に感謝、Omer
このように試すことができます。
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
状態の詳細:
破損データソースへの接続が切断されています。これは、接続が開かれた後にのみ発生します。この状態の接続を閉じてから、再度開くことができます。 (この値は、製品の将来のバージョン用に予約されています。)
本当に、それをテストする必要はありません。
マルチスレッドコンテキストで接続のインスタンスが共有されている場合、Connecting
状態がキャッチされる可能性があります。しかし、ここではそうではありません。
実際、Visual Studioでは、接続クラスにはsonnectionstateプロパティがあります。
接続状態が変更されると、接続状態変更イベントがトリガーされます。
この記事を確認してください。
https://msdn.Microsoft.com/en-us/library/aa326268(v = vs.71).aspx
私は@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;
}
}
}
}
このコードは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()
{
}
}
コメントできません...
...また、一般的な例外「catch(Exception ex)」のキャッチを避け、上記の例のような特定の例外のキャッチを試みます「catch(SqlException ex)」