41

我知道如果我实例化一个 SqlConnection 对象,我实际上是从连接池中获取一个连接。当我调用 Open() 时,它将打开连接。如果我对该 SqlConnection 对象调用 Close() 或 Dispose() 方法,它会返回到连接池。

但是,这并不能真正告诉我它是否真的关闭了,或者我是否仍然有与数据库的活动连接。

如何强制 SqlConnection 在网络级别关闭,或者至少告诉它何时关闭?

例子:

using(SqlConnection conn = new SqlConnection(DBConnString)) {

   conn.Open();
   SqlCommand cmd = conn.CreateCommand();
   ...
   cmd.ExecuteReader(CommandBehavior.CloseConnection);
   ...
}
  • 首次运行:300 毫秒
  • 第二次运行:100 毫秒
  • 第三次运行:100 毫秒
  • 等待很长时间(30分钟)后:300 ms

如果连接真正关闭,第二次和第三次运行也应该是 300 毫秒。但我知道连接并没有真正关闭那些运行(我检查了 SQL Server 的活动监视器)。执行身份验证/等不需要额外的 200 毫秒。

如何强制连接真正关闭?

想法

  • CommandBehavior.CloseConnection 有效吗?(显然不是?)
  • 在连接字符串中设置“Max Pool Size = 0”是否有效?(这将是一个昂贵的解决方案)
  • Dispose() 有效吗?

参考

4

7 回答 7

55

也许SqlConnection.ClearPool

于 2009-07-17T23:38:17.867 回答
26

Moe Sisko 的回答(Call SqlConnection.ClearPool)是正确的。

有时您需要连接才能真正关闭而不是返回池。例如,我有一个单元测试,它创建一个临时数据库、构建模式、测试一些东西,然后如果测试全部通过,则删除临时数据库。

当连接池处于活动状态时,drop database 命令会失败,因为仍有活动连接。从程序员的角度来看,所有 SQLConnections 都已关闭,但由于池仍保持打开状态,SQL Server 将不允许删除。

关于如何处理连接池的最佳文档是MSDN上 SQL Server Connection Pooling 上的此页面。人们不想完全关闭连接池,因为它可以通过重复打开和关闭来提高性能,但有时您需要在 SQLConnection 上调用“强制关闭”,以便它释放数据库。

这是通过 ClearPool 完成的。如果您SqlConnection.ClearPool(connection)在关闭/处置之前致电,那么当您关闭/处置时,它真的会消失。

于 2010-02-03T18:45:34.603 回答
14

如果您不想使用连接池,则必须在您的SqlConnection.ConnectionString属性中指定它。例如

"Data Source=MSSQL1;Database=AdventureWorks;Integrated Security=true;Pooling=false;"

处置或关闭SqlConnection对象只是要关闭连接并将其返回到连接池。

于 2009-07-17T22:46:13.697 回答
3

通常,您希望连接池完成它的工作——您不希望连接真正关闭。

为什么特别希望连接不返回池?

于 2009-07-17T23:49:23.490 回答
0

我看到您正在使用 .net,但由于这出现在 google 查询中,因此我可以给出 java 响应...

使用实现 Closeable() 的 DataSource 并在 DataSource 上调用 close。Hikari 支持 Closeable。

于 2019-01-27T23:48:48.337 回答
-1

CommandBehavior.CloseConnection由于这个事实,通常不鼓励 - 您不能确定连接是否会关闭。(我会试着找到一些具体的证据,我是从微弱的回忆中说出来的)。

Dispose()最可靠的方法,因为它隐式调用Close().

using@Alex 演示的构造只是另一种(程序员友好)编写try-finally构造的方式,其中添加了对象的隐式 Disposal。

编辑:(编辑问题后)

您对实际关闭的连接的担忧对我来说似乎没有根据。连接将简单地返回到池中,以便可以轻松地重用它,而无需进行所有初始化。这并不意味着 Connection 仍然主动连接到 DB。

于 2009-07-17T22:26:59.147 回答
-2

罗伯特的回答SqlConnection.ClearPool(TheSqlConn)正是我想要的。很高兴知道可以在必要时与池进行交互。

我的用例是:我们破坏了一个连接,让它回到池中,我们如何检测它被破坏并刷新它,所以下一个用户不会有问题。

解决方案是:检测到我们刚刚破坏了连接,并将其从池中完全清除,让池中充满新的连接。

十年来编写 SqlClient.SqlConnection 直到今天我什至从未想过与池进行交互。

于 2016-11-01T11:44:29.990 回答