我在使用.NET编写的代码中遇到了问题。
问题是在某个地方我有一些狡猾的数据库代码,这意味着一段时间后我得到以下错误:
超时已过期。超时期限 在获得之前经过了 从游泳池连接。这可能 已经发生,因为所有汇集 连接正在使用和最大池 达到了规模。
我知道这是因为某个地方我没有处理过我的一个datareader或类似的东西,这意味着它仍然打开了连接,因此它没有被返回到池中。我在我的代码中发现这种情况时遇到了一些问题。
所以我的问题:
有没有办法查询连接池以找出它正在使用的连接正在做什么。我只是想找到一种方法来查找正在运行的查询,以便让我找到有问题的代码。
为了它的价值,我没有权限在相关数据库上运行活动监视器以找出那种方式。
答案 0 :(得分:12)
有没有办法查询 连接池,找出它的内容 在使用连接正在做。
没有。并不是的。连接池是您的应用程序维护的(实际上是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();
}
但是,我确实提醒您不要这样做,因为它可能会阻塞您的数据库服务器,因为它允许您的应用程序在资源耗尽之前打开尽可能多的连接。
答案 1 :(得分:2)
您是否尝试加载SSMS并在相关数据库上运行sp_who2
?
USE [SomeDatabase]
EXEC sp_who2
这应该会告诉你某个时刻发生了什么。