【发布时间】:2012-08-08 09:00:05
【问题描述】:
问题:
为什么下面的代码会泄露连接?
public System.Data.DataTable GetDataTable()
{
System.Data.DataTable dt = new System.Data.DataTable();
string strConnectionString = "Data Source=localhost;Initial Catalog=MyDb;User Id=SomeOne;Password=TopSecret;Persist Security Info=False;MultipleActiveResultSets=False;Packet Size=4096;";
System.Data.SqlClient.SqlConnectionStringBuilder csb = new System.Data.SqlClient.SqlConnectionStringBuilder(strConnectionString);
csb.IntegratedSecurity = true;
string strSQL = "SELECT * FROM T_Benutzergruppen";
using (System.Data.SqlClient.SqlConnection sqlcon = new System.Data.SqlClient.SqlConnection(csb.ConnectionString))
{
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(strSQL, sqlcon))
{
if (sqlcon.State != System.Data.ConnectionState.Open)
{
sqlcon.Open();
}
// First attempt
//System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", sqlcon);
//sqlda.Fill(dt);
cmd.ExecuteNonQuery();
}
if(sqlcon.State != System.Data.ConnectionState.Closed)
sqlcon.Close();
}
//sqlcon.ConnectionString = csb.ConnectionString;
// Second attempt
//System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", csb.ConnectionString);
//sqlda.Fill(dt);
return dt;
}
如果我进入 SQL-Server 活动监视器,我会看到 Session 68
SELECT * FROM T_Benutzergruppen
补充问题:
如果有问题:
如果我注释掉除了 ConnectionStringBuilder 之外的所有内容,并且只在这个函数中执行下面的代码,为什么它也会泄漏连接?
// Second attempt
System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", csb.ConnectionString);
sqlda.Fill(dt);
注意:
executenonquery 没有任何意义,它只是用于测试目的。
如果我让它在调试器中运行,我会看到 sqlcon.Close();
get 被执行了,所以问题不在于
if(sqlcon.State != System.Data.ConnectionState.Closed)
【问题讨论】:
-
您不需要在您的
SqlConnection对象上显式调用.Close(),using块会在超出范围时为您执行此操作。您的代码很好,正如其他人已经指出的那样,这只是工作中的连接池。 -
@James:是的。现在我知道默认情况下池是打开的。
标签: c# .net sql ado.net database-connection