views:

360

answers:

6

I have come up with the following method to determine is a database is up and running. This trys to open a database connection and if it fails it return false.

private static bool IsDatabaseConnectionUp(string connectionString)
{
    System.Data.SqlClient.SqlConnection conn = null;

    try
    {
        conn = new SqlConnection(connectionString);

        conn.Open();

        return conn.State == System.Data.ConnectionState.Open;
    }
    catch (SqlException)
    {
        // There was an error in opening the database so it is must not up.
        return false;
    }
    finally
    {
        if (conn != null)
        {
            if (conn.State == System.Data.ConnectionState.Open)
            {
                conn.Close();
            }

            conn.Dispose();
        }
    }
}

Is this the best way to determine if this database is up? The reason I do not like this method it will rely on the timeout value, and will take as long as the timeout is set.

Is there a better way?

A: 

If you're interested in the state of that particular database (not the database server as a whole) then yes, that would be the best way of doing it.

tomlog
+2  A: 

This really depends on exactly what you are trying to determine. If you are truly looking to determine if "The server is running, and able to be accessed", then I would say that this is most likely the most effective manner. The reason I say this is that the server itself could be up, but it might not be accepting connections, OR the connection that the application is using might be invalid (Incorrect username/password).

Therefore, given this, the timeout is a needed thing, as you want to validate true connection. If you want to simply see if the server is there, you could try pinging, but that simply tells you if the device is active, not necessarily if SQL Server is fully up and running, and available.

Mitchel Sellers
A: 

Your pattern is close but there is one problem with it. Because SQLConnection implements IDisposable, you really should be disposing of your test connection before you return it.

try
    {
        using (System.Data.SqlClient.SqlConnection conn = new SqlConnection(connectionString))
        {

            conn.Open();

            return conn.State == System.Data.ConnectionState.Open;
        }
    }
    catch (SqlException)
    {
        // There was an error in opening the database so it is must not up.
        return false;
    }

As to what the other posters said, if all you want to do is see if a database instance is running you may be able to enumerate the processes on the system, or use a command line access to test the database, but either of those options is entirely dependent on the database vendor. Your method is generally ok for most applications.

womp
+1  A: 

Since you're specifically looking at a SQLServer connection, take the connection string into a SqlConnectionStringBuilder object and change the timeout value.

SqlConnectionStringBuilder csb = 
   new SqlConnectionStringBuilder(connectionString);
csb.ConnectTimeout = 5;
string newConnectionString = csb.ToString();

This way you control the timeout value. Remember, don't set it too low or you'll get false positives.

WaldenL
A: 

If your worried about the timeout, there are a few things you could try ...

You could try and ping the server. Unless ICMP packets are disallowed, this will tell you more quickly if your server is down. If you can't ping, you can't connect. Obviously it's no guarantee that you can connect, but it will make things quicker when you can't.

You could use a different connection string for your server up connection test. You generally don't need the full default time to make a connection, so you could probably lower it substantially.

If you can allow for slightly stale data, you could have a service that goes and checks the connection every X minutes (5 or 10 or whatever) and then go an ask that service for the most recent information. That is more like how a Witness acts.

JP Alioto
A: 

That may be a simplified code snippet, but shouldn't you have a conn.Dispose() or using(...) {...} statement?

Edit: nevermind, I see the comments.

Jeff Meatball Yang