"using"关键字不能关闭已打开的SQL连接。

6
我要翻译的内容是:

我参考了很久以前在Stack Overflow上发布的一篇文章。 Does End Using close an open SQL Connection

然而,我有一个问题。 我发现在SQL 2012 Express版和SQL 2008 Developer Edition上使用using根本不关闭连接。

这是我使用的代码。 该代码将遍历每个数据库并查找指定的特定表,但是,当它完成时,并且您在服务器上运行sp_who时,所有连接仍然存在。 状态为睡眠状态,cmd为“等待命令”,但是当您尝试创建数据库时,模型无法锁定,因为您仍然有一个打开的连接。 这是类中的错误吗?

using (SqlConnection conn = new SqlConnection("Data Source=" + ServerNameCombo.Text + ";Initial Catalog=master;Persist Security Info=True;User ID=" + UserNameEdit.Text + ";Password=" + PasswordEdit.Text))
{
    using (SqlCommand dbs = new SqlCommand("Select name from sysdatabases", conn))
    {
        conn.Open();
        using (SqlDataReader reader = dbs.ExecuteReader())
        {
            while (reader.Read())
            {
                using (SqlConnection dbconn = new SqlConnection("Data Source=" + ServerNameCombo.Text + ";Initial Catalog=" + reader["name"].ToString() + ";Persist Security Info=True;User ID=" + UserNameEdit.Text + ";Password=" + PasswordEdit.Text))
                {
                    using (SqlCommand dbscmd = new SqlCommand("Select name from sysobjects where name = '" + TableName + "'", dbconn))
                    {
                        dbconn.Open();
                        if (dbscmd.ExecuteScalar() != null)
                        {
                            DBNames += (DBNames != "" ? "," : "") + reader["name"].ToString();
                        }
                    }
                }
            }
        }
    }
}

你预计什么时候关闭这个连接? - Daniel A. White
1
这是连接池将其保持在该状态。请查看一下。您实际上可以在连接字符串中禁用它。 - Marcel N.
2
你可以通过移除另一个using块周围的{ }来合并using块,这样可以节省一些缩进... - Mark Rotteveel
1个回答

14

这是预期行为; 它关闭了“托管连接”,这意味着它释放了连接池中的底层连接。这使得连接人工保持打开状态,以便相同连接字符串和标识符的下一个托管连接可以使用现有的连接(在TDS流水线中设置重置位)以避免连接自旋延迟。

如果您不想要这个:在连接字符串中禁用连接池 (Pooling=false)。


有趣的是,楼主应该对连接池感到满意,因为他正在循环中打开和关闭同一个连接。 - Mark Rotteveel
@MarkRotteveel 这是真的,但我并没有使用同样的连接,因为我连接的数据库发生了变化。我发现物理连接不存在,这就是为什么连接仍然在服务器端的有趣之处。 - Jaques

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接