У меня есть несколько потоков, обращающихся к одной и той же базе данных (с одной и той же строкой подключения). Каждый поток:
использует приведенный ниже код, чтобы открывать свой собственный экземпляр подключения всякий раз, когда ему требуется одна
попытка
{
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; Имя приложения = имя_приложения