我在使用 .NET 编写的代码中遇到问题。
问题是我在某个地方有一些狡猾的数据库代码,这意味着一段时间后我会收到以下错误:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
我知道这是因为我没有在某个地方处理我的数据读取器之一或类似的东西,这意味着它仍然打开连接,因此它不会返回到池中。不过,我在查找代码中发生这种情况的位置时遇到了一些问题。
所以我的问题是:
有什么方法可以查询连接池以找出其正在使用的连接在做什么。我只是在寻找一种方法来查找正在运行的查询,以便找到有问题的代码。
就其值(value)而言,我无权在有问题的数据库上运行事件监视器来找出答案。
最佳答案
Is there any way to query the connection pool to find out what its in use connections are doing.
没有。并不真地。连接池是你的应用程序维护的东西(实际上是一个 List<DbConnectionInternal>
)如果你真的想要你可以通过反射或者如果你正在调试,通过本地或观察窗口(见下文)获得池中的连接,但是您无法从那里了解该连接上发生的事情,或者哪个对象应该调用 Connection.Close(或 Dispose)。所以这没有帮助
如果幸运的话,您可以在超时时执行 sp_who 或 sp_who2,当您用完池连接时,但很可能大多数结果看起来像这样。
SPID Staus Login Hostname Blkby DBname Command ....
---- ------- ----- --------- ----- ------ ----------------
79 sleeping uName WebServer . YourDb AWAITING COMMAND .....
80 sleeping uName WebServer . YourDb AWAITING COMMAND .....
81 sleeping uName WebServer . YourDb AWAITING COMMAND .....
82 sleeping uName WebServer . YourDb AWAITING COMMAND .....
这意味着是的,您的应用程序确实打开了很多连接但没有关闭它们,甚至没有对它们执行任何操作。
解决此问题的最佳方法是使用 ADO.NET Performance Counters 分析您的应用程序并密切关注NumberOfReclaimedConnections
并进行彻底的代码审查。
如果你真的很绝望,你可以在遇到这个问题时清除池。
using (SqlConnection cnn = new SqlConnection("YourCnnString"))
{
try
{
cnn.Open();
}
catch (InvalidOperationException)
{
SqlConnection.ClearPool(cnn);
}
cnn.Open();
}
但是我提醒您不要这样做,因为它有可能阻塞您的数据库服务器,因为它允许您的应用程序在资源耗尽之前打开服务器允许的尽可能多的连接。
关于c# - 如何查找正在使用我的连接池中的连接的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6599053/