@usr我是having a disagreement in another question关于.NET是否会清除已经空闲的开放连接,但仍保持一个保持参考。
我维护based on documentation,如果物理连接闲置一段时间,即使SQLConnection
对象引用仍然保留,它也会在一段时间后被回收。
usr声称这不会发生,它只会回收不再有引用的连接。他的断言会使连接池不可靠并且会对交易造成严重破坏。
我承认,文档对于持有引用的问题含糊不清。
我正在寻找一个权威的答案,而不仅仅是猜测。要么有人试验过并证明了这两种情况,要么是对内部工作有所了解的人。
那是哪一个?
编辑:
我认为这里的混淆是“封闭”的术语。似乎是这种情况是文档指的是将物理连接关闭为“从池中删除”连接。而“关闭”是指将开放的物理连接释放回池中以便重复使用。
打开连接仍然可以中止,但是如果客户端应用程序仍然保持打开状态(即客户端应用程序尚未在中止连接上调用关闭),则不清楚该标记是否将其标记为无效。不确定它是否真的很重要,而不是池数的一部分。
答案 0 :(得分:2)
我可以100%确定地告诉你,连接不会返回池直到发布。我有一个会话创建一个临时表,并在等待用户输入时将其挂起。用户在6分钟后返回,按下按钮,然后在相同的 SPID 上继续,并且生命继续临时表。
应用逻辑,这是有道理的,因为如果你因为你已经闲置了X分钟而失去了SPID,你能想象到的破坏吗?你是否应该继续" ping" SQL Server只是为了让它保持活动? (这将是疯狂的)
<小时/> 你似乎混淆了两个概念。关闭连接后,它将返回池。如果它超出范围,则隐式关闭 - &gt;返回游泳池。引用&#34;空闲&#34;指的是当池中的连接变为空闲时,而不是当它被主动引用且未关闭时。即使在池中也没有保持连接,以便有资格进行任何类型的清理。从池中释放资源是有道理的,因为Web应用程序可以轻松地连接到100个连接,然后在接下来的几个月内保持大约20个左右的活动并发连接。
答案 1 :(得分:1)
.NET是否会清除已经空闲的开放连接,但仍保持保持引用
“持有参考”在这里并不重要,重点是“开放”。要正确回收连接,您需要Dispose()
或Close()
它。
答案 2 :(得分:0)
我刚刚运行了以下程序:
var conn = new SqlConnection("...");
conn.Open();
conn.ExecuteNonQuery("select null");
Thread.Sleep(TimeSpan.FromMinutes(11));
conn.ExecuteNonQuery("select null");
它成功运行(使用自定义帮助器方法,因此您无法直接运行它)。
这当然不能证明任何事情(只有当它没有正确运行时)。反射器显示池在6.5分钟后第一次清理,之后每隔30秒清理一次:
private Timer CreatePruningTimer()
{
return new Timer(new TimerCallback(this.PruneConnectionPoolGroups), null, 240000, 30000);
}
所以测试应该暴露出这个问题。
现在,文档中的句子并不是特别清楚。它没有提到GC甚至是对象引用(在你的问题中你说它确实如此,但事实并非如此)。
连接池会定期扫描要查找的连接池 未被Close或Dispose关闭的未使用连接 收回它找到的那些。如果您的应用程序未明确关闭 或处置它的连接,它可能需要相当长的一段时间 连接pooler来收回它们,所以最好确保你 在您的连接中显式调用Close和Dispose。
我不相信。用贝叶斯语来说,微软的文档是有力的证据,但如果有强有力的反证据,可以得出相反的结论。
我有以下证据表明没有理由没有关闭开放式连接: