Я вижу страшный "Истекший период ожидания до получения соединения из пула".
Я искал код для любых закрытых подключений db, но не смог найти.
Что я хочу сделать, так это следующее: в следующий раз, когда мы получим эту ошибку, у вас есть системный дамп, список которых обрабатывает или обрабатывает HTTP-запросы, поэтому я могу выяснить, какой код вызывает проблему.
Еще лучше было бы посмотреть, как долго эти ручки были сохранены, поэтому я мог заметить используемые, но незакрытые соединения.
Есть ли способ сделать это?
Ответ 1
Есть несколько хороших ссылок для мониторинга пулов соединений. Сделайте поиск google для "мониторинга пула соединений .net".
Одна статья, на которую я ссылался некоторое время назад, была статья Билла Вона (обратите внимание, что она устарела, но все еще содержит полезную информацию). В нем есть информация о мониторинге пулов подключений, но некоторые большие сведения о том, где могут возникать утечки.
Для мониторинга он предлагает:
"Контроль пула соединений
Хорошо, поэтому вы открыли соединение и закрыли его, и хотите узнать, соединение все еще на месте - томятся в пуле соединений на надувной матрас. Ну, есть несколько способов определить, сколько соединения все еще на месте (все еще подключены) и даже то, что они делаем. Я обсуждаю некоторые из них здесь и в моей книге:
. Используйте SQL Profiler с SQLProfiler TSQL_Replay шаблон для трассировки. Для тех, кто знаком с Profiler, это проще, чем опрос с использованием SP_WHO.
. Запустите SP_WHO или SP_WHO2, которые возвращают информацию из таблица sysprocesses во всех рабочих процессах, показывающая текущий статус каждого процесса. Как правило, один SPID-серверный процесс за подключение. Если вы назвали свое соединение, используя имя приложения аргумент в строке соединения, его легко найти.
· Используйте монитор производительности (PerfMon) для мониторинга пулов и соединения. Я подробно расскажу об этом ниже.
· Мониторинг счетчиков производительности в коде. Этот вариант позволяет вы можете отобразить или просто контролировать работоспособность пула соединений и количество установленных соединений. Я обсуждаю это в последующий раздел в этой статье."
Изменить:
Как всегда, ознакомьтесь с некоторыми другими аналогичными сообщениями здесь на SO
Второе редактирование:
Как только вы подтвердите, что соединения не будут восстановлены пулом, вы можете попытаться использовать событие StateChange, чтобы подтвердить, когда соединения открываются и закрываются. Если вы обнаружите, что открываются гораздо больше изменений состояния, чем закрыты, это указывает на то, что где-то есть утечки. Затем вы также можете регистрировать данные в событии statechanged вместе с меткой времени, и если у вас есть другой журнал в вашем приложении, вы можете начать анализировать файлы журнала для случаев, когда, как представляется, изменения состояния закрыты для открытия, с нет соответствующего открытого для закрытия. См. эту ссылку для получения дополнительной информации о том, как обращаться с StateChangedEvent.
Ответ 2
Если вам повезло, что создание/открытие соединений централизовано, то следующий класс должен упростить обнаружение утечек соединений. Наслаждайтесь:)
/// <summary>
/// This class can help identify db connection leaks (connections that are not closed after use).
/// Usage:
/// connection = new SqlConnection(..);
/// connection.Open()
/// #if DEBUG
/// new ConnectionLeakWatcher(connection);
/// #endif
/// That it. Don't store a reference to the watcher. It will make itself available for garbage collection
/// once it has fulfilled its purpose. Watch the visual studio debug output for details on potentially leaked connections.
/// Note that a connection could possibly just be taking its time and may eventually be closed properly despite being flagged by this class.
/// So take the output with a pinch of salt.
/// </summary>
public class ConnectionLeakWatcher : IDisposable
{
private readonly Timer _timer = null;
//Store reference to connection so we can unsubscribe from state change events
private SqlConnection _connection = null;
private static int _idCounter = 0;
private readonly int _connectionId = ++_idCounter;
public ConnectionLeakWatcher(SqlConnection connection)
{
_connection = connection;
StackTrace = Environment.StackTrace;
connection.StateChange += ConnectionOnStateChange;
System.Diagnostics.Debug.WriteLine("Connection opened " + _connectionId);
_timer = new Timer(x =>
{
//The timeout expired without the connection being closed. Write to debug output the stack trace of the connection creation to assist in pinpointing the problem
System.Diagnostics.Debug.WriteLine("Suspected connection leak with origin: {0}{1}{0}Connection id: {2}", Environment.NewLine, StackTrace, _connectionId);
//That it - we're done. Clean up by calling Dispose.
Dispose();
}, null, 10000, Timeout.Infinite);
}
private void ConnectionOnStateChange(object sender, StateChangeEventArgs stateChangeEventArgs)
{
//Connection state changed. Was it closed?
if (stateChangeEventArgs.CurrentState == ConnectionState.Closed)
{
//The connection was closed within the timeout
System.Diagnostics.Debug.WriteLine("Connection closed " + _connectionId);
//That it - we're done. Clean up by calling Dispose.
Dispose();
}
}
public string StackTrace { get; set; }
#region Dispose
private bool _isDisposed = false;
public void Dispose()
{
if (_isDisposed) return;
_timer.Dispose();
if (_connection != null)
{
_connection.StateChange -= ConnectionOnStateChange;
_connection = null;
}
_isDisposed = true;
}
~ConnectionLeakWatcher()
{
Dispose();
}
#endregion
}
Ответ 3
Я использовал этот
http://www.simple-talk.com/sql/performance/how-to-identify-slow-running-queries-with-sql-profiler/
чтобы найти длинные хранимые процедуры раньше, я смогу вернуться и найти метод, называемый SP.
Не знаю, поможет ли это