Использование (var connection = new SqlConnection ("ConnectionString")) все еще закрывает / удаляет соединение при ошибке? - PullRequest
1 голос
/ 26 сентября 2011

У меня есть следующий код

try
{
    using (var connection = new SqlConnection(Utils.ConnectionString))
    {
        connection.Open();

        using (var cmd = new SqlCommand("StoredProcedure", connection))
        {                            
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            var sqlParam = new SqlParameter("id_document", idDocument);
            cmd.Parameters.Add(sqlParam);

            int result = cmd.ExecuteNonQuery();
            if (result != -1)
                return "something";

            //do something here

            return "something else";
        }
    }

    //do something
}
catch (SqlException ex)
{
    return "something AKA didn't work";
}

Вопрос в том, закрывается ли var connection, если между скобками using ({ }) возникает непредвиденная ошибка?

Проблема в том, что большинство моих вызовов хранимых процедур выполняются таким образом, и в последнее время я получаю эту ошибку:

System.InvalidOperationException: Истекло время ожидания.Время ожидания истекло до получения соединения из пула.Это могло произойти из-за того, что все пулы подключений использовались и был достигнут максимальный размер пула.

Другой способ доступа к БД - через nHibernate.

Ответы [ 5 ]

4 голосов
/ 26 сентября 2011

с помощью Statement (C # Reference)

С помощью оператора using вызывается Dispose, даже если происходит исключение во время вызова методов для объекта.Вы можете достичь того же результата, поместив объект в блок try, а затем вызвав Dispose в блоке finally;на самом деле, именно так оператор using переводится компилятором.Приведенный выше пример кода расширяется до следующего кода во время компиляции (обратите внимание на дополнительные фигурные скобки, чтобы создать ограниченную область видимости для объекта):

3 голосов
/ 26 сентября 2011

Да, если он попадет в тело оператора using, он будет расположен в конце ... независимо от того, достигли ли вы конца блока нормально, завершились с помощью оператора возврата или было сгенерировано исключение.По сути, оператор using эквивалентен блоку try / finally.

Является ли это only местом, где вы приобретаете соединение?Может быть, ваша хранимая процедура где-то заблокирована, что делает множество соединений действительно «занятыми» в том, что касается кода клиента?

1 голос
/ 01 октября 2011

Если в вашем пуле соединений заканчиваются доступные соединения, если вы находитесь в распределенной среде и используете много приложений для доступа к SQL Server, но все они используют одну и ту же строку соединения, то все они будут использовать один и тот же пул всервер.Чтобы обойти это, вы можете изменить строку подключения для каждого приложения, установив для идентификатора соединения Workstation значение Environment.MachineName.Это заставит сервер видеть каждое соединение как отдельное и предоставлять пул для каждой машины вместо совместного использования пула.

В приведенном ниже примере мы даже передаем токен, чтобы приложение на одном компьютере могло иметь несколько пулов.

Пример:

    private string GetConnectionStringWithWorkStationId(string connectionString, string connectionPoolToken)
    {
        if (string.IsNullOrEmpty(machineName)) machineName = Environment.MachineName;

        SqlConnectionStringBuilder cnbdlr;
        try
        {
            cnbdlr = new SqlConnectionStringBuilder(connectionString);
        }
        catch
        {
            throw new ArgumentException("connection string was an invalid format");
        }

        cnbdlr.WorkstationID = machineName + connectionPoolToken;

        return cnbdlr.ConnectionString;
    }
0 голосов
/ 03 января 2013

Вот ссылка:

http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx

Что я знаю, так это то, что если вы используете объект в предложении using {}, этот объект наследует интерфейс IDisposable (то есть SqlConnection наследует DbConnection, а DbConnection наследует IDisposable), что означает, что если вы получите исключение, любой объект будет закрыты и расположены правильно.

0 голосов
/ 26 сентября 2011

Замените свой код выше .. этим .. и проверьте снова ..

try
{
    using (var connection = new SqlConnection(Utils.ConnectionString))
    {
        connection.Open();
        using (var cmd = new SqlCommand("StoredProcedure", connection))
        {                            
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            var sqlParam = new SqlParameter("id_document", idDocument);
            cmd.Parameters.Add(sqlParam);

            int result = cmd.ExecuteNonQuery();
            if (result != -1)
                return "something";

            //do something here

            return "something else";

        }

        connection.Close();
        connection.Dispose();
    }

    //do something

}
catch (SqlException ex)
{
    return "something AKA didn't work";
}
...