如何强制SqlConnection在物理上关闭,同时使用连接池?

Jef*_*ang 40 c# sql ado.net database-connection connection-pooling

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

但是,这并没有真正告诉我它是否真的关闭,或者我是否仍然有一个与数据库的活动连接.

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

例:

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

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

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

如何强制连接真正关闭?

思路

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

参考

Rob*_*oun 25

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

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

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

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

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

  • 您可以通过在关闭连接之前发出 `use master;` 来解决问题*(“当连接池处于活动状态时,删除数据库命令会失败,因为仍然存在活动连接”)*。它不回答OP的问题,但它解决了你的问题。 (2认同)

Zip*_*pyV 9

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

"Data Source=MSSQL1;Database=AdventureWorks;Integrated Security=true;Pooling=false;"
Run Code Online (Sandbox Code Playgroud)

处理或关闭SqlConnection对象只是关闭连接并将其返回到连接池.