Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如果仍然存在对池SQL连接的引用,是否会清除池SQL连接?_.net_Sql Server_Connection Pooling_Sqlconnection - Fatal编程技术网

.net 如果仍然存在对池SQL连接的引用,是否会清除池SQL连接?

.net 如果仍然存在对池SQL连接的引用,是否会清除池SQL连接?,.net,sql-server,connection-pooling,sqlconnection,.net,Sql Server,Connection Pooling,Sqlconnection,我关心的是.NET是否会清除已空闲的打开连接,但仍保留保留的引用 我认为,如果物理连接空闲一段时间,即使SQLConnection对象引用保持不变,它也会在一段时间后被回收 usr声称这不会发生,它只回收不再有引用的连接。他的断言,因为这将使连接池不可靠,并会对事务造成严重破坏 我承认,文件中关于保留参考资料的问题含糊不清 我在寻找一个权威的答案,而不仅仅是猜测。要么有人已经试验并证明了这两种情况,要么有人了解内部工作原理 那是哪一个呢 编辑: 我认为这里的混淆是“封闭”的术语。情况似乎是,文档

我关心的是.NET是否会清除已空闲的打开连接,但仍保留保留的引用

我认为,如果物理连接空闲一段时间,即使
SQLConnection
对象引用保持不变,它也会在一段时间后被回收

usr声称这不会发生,它只回收不再有引用的连接。他的断言,因为这将使连接池不可靠,并会对事务造成严重破坏

我承认,文件中关于保留参考资料的问题含糊不清

我在寻找一个权威的答案,而不仅仅是猜测。要么有人已经试验并证明了这两种情况,要么有人了解内部工作原理

那是哪一个呢

编辑:


我认为这里的混淆是“封闭”的术语。情况似乎是,文档将关闭物理连接称为从池中“删除”连接。而“关闭”是指将打开的物理连接释放回池中以供重用


打开的连接仍然可以中止,但如果客户端应用程序仍将其保持为打开状态(即客户端应用程序尚未调用中止连接的关闭),则池程序是否将其标记为无效尚不清楚,但不确定这是否真的重要,而不是作为池计数的一部分。

我可以100%肯定地告诉您,连接在释放之前不会返回池。我让一个会话创建一个临时表,并在等待用户输入时将其挂起。用户在6分钟后返回,按下一个按钮,它在同一个SPID上继续,生活在临时表上继续

应用逻辑,这是有道理的,因为你能想象如果你仅仅因为闲置了X分钟就失去SPID会造成多大的破坏吗?您是否应该继续使用命令“ping”SQL Server以使其保持活动状态?(这太疯狂了)



您似乎混淆了两个概念。当连接关闭时,它将返回池。如果超出范围,则隐式关闭->返回池。对“idle”的引用是指池中的连接变为空闲时,而不是当它被主动引用且未关闭时。保留的连接甚至不在池中,因此无法进行任何类型的清除。从池中释放资源是有意义的,因为一个web应用可以很容易地突发到100个连接,然后在接下来的几个月里保持大约20个活动的并发连接。

我刚刚运行了以下程序:

        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

我不相信它。用贝叶斯的术语来说,微软文档是有力的证据,但如果有有力的反证据,人们可能会得出相反的结论

我有以下证据表明,打开的连接不会无故关闭:

  • 这将注入不可预防的随机故障(仅通过重试)
  • 它将中止正常的事务
  • 这将使长期运行的事务变得不可能
  • 我看不出为什么会有这种行为
  • 文档中的句子可以用以下方式解释:池周期性地返回尚未关闭但其对应的SqlConnection对象已被GC’ed的连接(通过使用WeakReference或其他方法检测)。我猜微软的文档作者就是这个意思,或者不理解这个问题(似乎有道理!)
  • 测试没有证明问题
  • SSMS如何运行长达一小时的查询?SSM应受到相同的限制
  • NET是否将清除已空闲但仍保留保留引用的打开连接


    “保留参考”在这里并不重要,重点是“开放”。要正确回收连接,您需要
    Dispose()
    Close()

    嗯,默认连接超时是30秒-超过此超时将导致连接关闭并出现异常并被池回收。但是,如果超时是无限的,则打开的连接将不会被回收。@Oded-我认为超时只是框架尝试连接的时间。尽管如此,如果是真的,它并没有真正解决这个问题。我可能在考虑连接的生命周期……你认为文档的哪一部分说空闲连接可以/将被回收?@HenkHolterman-关于删除连接的部分。你还没有完全理解这个问题的微妙之处。问题是关于连接池清理系统。这个清理系统是什么/在哪里?连接池程序定期扫描连接池,查找未通过关闭或处置关闭的未使用的连接,并回收找到的连接“是的,您是对的”。但是“未使用”的定义不是很好。B