3
votes

I am receiving this error which cause my application to stop working. Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

However I have not reached my max connection pool. I have RDS and in my monitoring page, I found that number of connections was 33 at the time this error happens and my max one is 100 by default.

So, I was wondering that this could be due to a leak in my connection.

Here is the DBLayer class that I am using to connect to database.

public static DataTable GetDataTable(SqlCommand command, IsolationLevel isolationLevel = IsolationLevel.ReadUncommitted)
{
    using (new LoggingStopwatch("Executing SQL " + command.CommandText, command.Parameters))
    {
        using (var connection = new SqlConnection(connectionString))
        using (var dataAdapter = new SqlDataAdapter(command))
        {
            command.Connection = connection;
            command.CommandTimeout = ShopexConfiguration.SqlTimeout;
            connection.Open();
            var transaction = connection.BeginTransaction(isolationLevel);
            command.Transaction = transaction;
            try
            {
                var result = new DataTable();
                dataAdapter.Fill(result);
                transaction.Commit();
                return result;
            }
            catch
            {
                try
                {
                    transaction.Rollback();
                }
                catch (Exception)
                {
                    //
                    // This catch block will handle any errors that may have occurred 
                    // on the server that would cause the rollback to fail, such as 
                    // a closed connection.
                }
                throw;
            }
        }
    }
}

I am just wondering, will this cause a connection leak?

I have seen this blog :

https://blogs.msdn.microsoft.com/spike/2008/08/25/timeout-expired-the-timeout-period-elapsed-prior-to-obtaining-a-connection-from-the-pool/

Any help is appreciated?

2
This may be a long shot, but is there a limit to the number of open connections per user at the server?Kris Vandermotten

2 Answers

1
votes

Are you sure, that your query don't reach execution timeout? SqlConnection.ConnectionTimeout have default value 15 seconds

Also do you have some connection timeout values in your connectionString format is: "....;Connection Timeout=10..."

1
votes

I think you should close your connection in your finally statement like below:

public static DataTable GetDataTable(SqlCommand command, IsolationLevel isolationLevel = IsolationLevel.ReadUncommitted)
{
    using (new LoggingStopwatch("Executing SQL " + command.CommandText, command.Parameters))
    {
        using (var connection = new SqlConnection(connectionString))
        using (var dataAdapter = new SqlDataAdapter(command))
        {
            command.Connection = connection;
            command.CommandTimeout = ShopexConfiguration.SqlTimeout;
            connection.Open();
            var transaction = connection.BeginTransaction(isolationLevel);
            command.Transaction = transaction;
            try
            {
                var result = new DataTable();
                dataAdapter.Fill(result);
                transaction.Commit();
                return result;
            }
            catch
            {
                try
                {
                    transaction.Rollback();
                }
                catch (Exception)
                {
                    //
                    // This catch block will handle any errors that may have occurred 
                    // on the server that would cause the rollback to fail, such as 
                    // a closed connection.
                }
                finally { connection.Close(); }
                throw;
            }
        }
    }
}

Maybe it solves your problem, because you are rollbacking your transaction in catch statement without closing your existing connection you can also use below condition before you are going to open your SQL connection :

    if (connection.State == ConnectionState.Closed) {
        // Open your connection here
        connection.Open();
    }
// Do your logic here

Hope it will helps you.

Thanks