gpt4 book ai didi

asp.net - 如何找到泄漏的数据库连接池句柄?

转载 作者:行者123 更新时间:2023-12-03 14:50:41 25 4
gpt4 key购买 nike

我看到可怕的“在从池中获取连接之前已过超时时间”错误。

我在代码中搜索了任何未关闭的数据库连接,但找不到任何连接。

我想要做的是:下次我们收到此错误时,让系统转储一个列表,其中列出了哪些 proc 或 http 请求持有所有句柄,这样我就可以找出导致问题的代码。

更好的办法是看看这些 Handlebars 已经握住了多长时间,这样我就可以发现使用过但未关闭的连接。

有没有办法做到这一点?

最佳答案

如果你足够幸运,连接创建/打开是集中的,那么下面的类应该可以很容易地发现泄漏的连接。享受 :)

using System.Threading; // not to be confused with System.Timer
/// <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's 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's 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's 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
}

关于asp.net - 如何找到泄漏的数据库连接池句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9004602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com