Пул соединений с возможными разорванными соединениями

У меня есть несколько потоков, обращающихся к одной и той же базе данных (с одной и той же строкой подключения). Каждый поток:

  • создает свой собственный экземпляр SqlConnection, используя ту же строку подключения
  • использует приведенный ниже код, чтобы открывать свой собственный экземпляр подключения всякий раз, когда ему требуется одна

    попытка
     {
    wasOpened = соединение.Состояние == Состояние соединения.Открытым;
    
    если (connection.State == ConnectionState.Closed)
     {
    соединение.Открыть();
     }
     }
    поймать (исключение ex)
     {
    throw new Exception(string.Format("Невозможно установить соединение с источником данных {0}! Причина: {1} - полный стек {2}",
    connection.Database, ex.Message, ex.StackTrace == null ? "NULL": ex.StackTrace.ToString()));
     }
    

Пока мы протестировали этот код на 2 серверах, и один сервер иногда выдает исключение в методе SqlConnection.Open. Вот сообщение об исключении, которое мы получаем от блока catch:

Невозможно установить соединение с источником данных xyz! Причина: Неверная операция. Соединение закрыто. - полный стек

в System.Data.SqlClient.SqlConnection.GetOpenConnection()
в System.Data.SqlClient.SqlConnection.get_Parser()
в System.Data.SqlClient.SqlConnection.Open()

Проверка метода SqlConnection.GetOpenConnection показывает, что innerConnectionравно null:

internal SqlInternalConnection GetOpenConnection()
{
    SqlInternalConnection innerConnection = this.InnerConnection as SqlInternalConnection;
    if (innerConnection == null)
    {
        throw ADP.ClosedConnectionError();
    }
    return innerConnection;
}

Мне остается неясным: почему пул соединений иногда дает мне разорванное соединение (внутреннее соединение == ноль)?

Редактировать #1: в коде нет статических свойств - мы всегда закрываем соединение, когда это необходимо, wasOpened используется в нашем методе Close и означает: если соединение уже было открыто, когда наш Open вызывается, просто оставьте его открыть при закрытии, иначе закрыть. Однако это не связано с проблемой, описанной в этом вопросе (innerConnection == null).

Правка №2: Сервер: SQL Server 2008 R2, Windows Server 2003. Клиент: Windows Server 2003 (код выполняется в пользовательском компоненте пакета служб SSIS).Строка подключения: Источник данных = имя_сервера; Исходный каталог = имя_базы данных; Интегрированная безопасность = SSPI; Имя приложения = имя_приложения

6
задан Filip Popović 21 March 2012 в 00:08
поделиться