据我所知,如果我实例化一个SqlConnection对象,我实际上是从连接池中获取连接。当我调用Open()时,它将打开连接。如果我在该SqlConnection对象上调用Close()或Dispose()方法,它将返回到连接池。
然而,这并没有真正告诉我它是否真的关闭了,或者我是否仍然拥有与数据库的活动连接。
如何强制SqlConnection在网络级别关闭,或者至少告诉它什么时候关闭?
示例:
using(SqlConnection conn = new SqlConnection(DBConnString)) {
conn.Open();
SqlCommand cmd = conn.CreateCommand();
...
cmd.ExecuteReader(CommandBehavior.CloseConnection);
...
}
如果连接是TRULY关闭,则第二次和第三次运行也应该是300 ms。但我知道这些运行并没有真正关闭连接(我检查了SQL Server的活动监视器)。它不需要额外的200ms来执行身份验证/等。
如何强制连接真正关闭?
观
参考
答案 0 :(得分:51)
答案 1 :(得分:24)
Moe Sisko的回答(致电SqlConnection.ClearPool
)是正确的。
有时您需要连接才能真正关闭而不是返回池中。作为一个例子,我有一个单元测试,它创建一个临时数据库,构建模式,测试一些东西,然后在测试全部通过时删除临时数据库。
当连接池处于活动状态时,drop database命令会失败,因为仍有活动连接。从程序员的角度来看,所有SQLConnections都已关闭,但由于池仍然保持一个打开状态,因此SQL Server不允许丢弃。
有关如何处理连接池的最佳文档是MSDN上的this page on SQL Server Connection Pooling。人们不希望完全关闭连接池,因为它通过重复打开和关闭来提高性能,但有时您需要在SQLConnection上调用“强制关闭”,以便它将释放数据库。
这是通过ClearPool完成的。如果你在关闭/处置之前致电SqlConnection.ClearPool(connection)
,当你关闭/处置它时它会真的消失。
答案 2 :(得分:9)
如果您不想使用连接池,则必须在SqlConnection.ConnectionString
属性中指定它。例如
"Data Source=MSSQL1;Database=AdventureWorks;Integrated Security=true;Pooling=false;"
处理或关闭SqlConnection
对象只是关闭连接并将其返回到连接池。
答案 3 :(得分:3)
通常,您希望连接池完成其工作 - 您不希望连接真正关闭。
为什么特别要求连接不返回池?
答案 4 :(得分:0)
我看到您正在使用.net,但是正如Google查询中显示的那样,请允许我给出Java响应...
使用实现Closeable()的数据源,并在数据源上调用close。 Hikari支持Closeable。
答案 5 :(得分:-1)
CommandBehavior.CloseConnection
- 您无法确定Connection是否会被关闭。 (我会试着找到一些具体的证据,我这是从微弱的回忆中说出来的。)
Dispose()
是最可靠的方式,因为它隐式调用Close()
。
@Alex演示的using
构造只是另一种(程序员友好的)编写try-finally
构造的方式,其中添加了隐含的对象Disposal。
编辑:(编辑后提问)
您对连接实际关闭的担忧对我来说似乎是没有根据的。连接将简单地返回到池,以便可以轻松地重用它,而无需完成所有初始化。这并不意味着Connection仍然主动连接到DB。
答案 6 :(得分:-2)
SqlConnection.ClearPool(TheSqlConn)
的回答完全符合我的要求。很高兴知道游泳池可以在必要时与之互动。
我的用例是:我们破坏了连接,让它回到池中,如何检测到它已经毁了并刷新它,所以下一个用户不会遇到问题。
解决方案是:检测到我们刚刚破坏了连接,并完全从池中清除它,让池重新填满新连接。
编写SqlClient.SqlConnection十年了,直到今天我才想到与池进行交互。