В течение многих лет я испытывал очень странные проблемы во всех моих веб-приложениях, которые подключаются к SQL-серверу.
Проблема заключается в том, что если что-то происходит с сервером базы данных (перезагрузка сервера или другая проблема), веб-приложение перестает работать с этой точки, даже если сервер базы данных жив и после этого.
Случается, что каждая операция ADO.NET(ExecuteNonQuery, CreateReader, BeginTransaction,...) завершается с InvalidOperationException: "Неверная операция. Соединение закрыто". Кажется, что вызов SqlConnection.Open() извлекает соединение из пула приложений, который... закрыт!
В соответствии с документацией пул подключений должен автоматически удалять отключенные соединения из пула соединений, но при закрытом соединении не считается "отключенным", поэтому вызов SqlConnection.Open() счастливо возвращает закрытое соединение, считая его открытым, не проверяя это.
Мое текущее обходное решение - проверить состояние соединения сразу после его открытия:
using (SqlConnection connection = new SqlConnection( connectionString ))
{
connection.Open();
if (connection.State != ConnectionState.Open)
{
SqlConnection.ClearAllPools();
connection.Open();
}
// ...
}
Обходной путь, похоже, сейчас работает, но я не чувствую себя комфортно.
Итак, мои вопросы:
- Почему SqlConnection.Open() возвращает закрытые соединения из пула соединений?
- Является ли мой способ обхода действительным?
- Есть ли лучший способ справиться с этим?