C# - SQL连接不会关闭

时间:2017-01-02 14:57:17

标签: c# sql-server

我正在制作一个与某些SQL Server数据库交互的C#程序。问题是如果我连接到数据库(dbA)然后关闭此连接并打开另一个连接到另一个数据库(dbB)然后执行还原dbA,则SqlException会触发说该数据库(dbA)正在使用中。但是,如果我执行程序并仅连接到dbB,我可以毫无问题地恢复其他数据库,就像第一个连接被保存一样。无论如何这里是连接应该打开和关闭的代码:

private bool CheckConnection()
    {
        bool res = false;
        string conString = string.Empty;
        if (!String.IsNullOrEmpty(serverBox.Text) && !String.IsNullOrEmpty(dbBox.Text))
        {
            conString = ConcatConString(dbBox.Text);
            using (SqlConnection conn = new SqlConnection(conString))
            {
                conn.Open();
                if (conn.State == ConnectionState.Open)
                {
                    res = true;
                }
            }
        }        
        return res;
    }

2 个答案:

答案 0 :(得分:3)

ADO.NET使用连接池来重用昂贵的连接对象。当您关闭连接时,将回滚任何现有事务,重置其服务器端状态,并将其置于连接池中,以便为下一个Open命令进行操作。

但是,当您尝试采取诸如关闭服务器,恢复数据库等的激烈操作时,仍然将服务器连接视为服务器连接。这意味着您必须采取明确的操作并告诉服务器它没关系继续。

在这种情况下,您需要将数据库设置为SINGLE USER模式,执行还原操作,然后将其恢复为MULTI USER模式,例如:

ALTER DATABASE [MyDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE [MyDB] ...
ALTER DATABASE [MyDB] SET MULTI_USER

当您在恢复时选中“关闭现有数据库连接”选项时,这就是SSMS所做的事情

如果您想给现有连接留一些时间,也可以使用WITH ROLLBACK AFTER xx SECONDS。但在这种情况下,您将覆盖数据库。

答案 1 :(得分:0)

关闭连接不会在数据库中关闭它,它只返回与ADO.Net维护的池的连接。通常我永远不会建议这样做,但似乎你可能有一个合法的情况来禁用连接池。

在连接字符串中,将Pooling属性设置为nofalse,并且连接应该在服务器上实际关闭。

您可以通过在以下代码中启用或禁用连接池的SSMS中运行sp_who2来观察其工作原理:

class Program
{
    static void Main(string[] args)
    {
        SqlConnectionStringBuilder bldr = new SqlConnectionStringBuilder();
        bldr.IntegratedSecurity = true;
        bldr.InitialCatalog = "YourDB";
        bldr.DataSource = "(localdb)\\YourServer";
        bldr.Pooling = false;  //Comment and uncomment this and run sp_who2

        using (SqlConnection con = new SqlConnection(bldr.ConnectionString))
        {
            con.Open();
        }
    }
}
  

更新

除非你的程序是唯一连接的程序,否则不要这样做。我得到的印象是该程序专门用于恢复数据库。如果你在数据库上有其他客户端,那么这将会影响性能。