代码之家  ›  专栏  ›  技术社区  ›  Luke Foust

Sql Server 2008在数据库删除后关闭连接

  •  3
  • Luke Foust  · 技术社区  · 6 年前

    在删除并重新创建给定数据库之后,SQL Server在删除连接时遇到问题,下次尝试对同一数据库上的新连接执行命令时,我得到:

    这是TCP版本(如果我尝试连接到另一台服务器)

    向服务器发送请求时发生传输级别错误。(提供程序:TCP提供程序,错误:0-远程主机已强制关闭现有连接。)

    以下是重新设置问题的步骤:

    1. 打开与数据库的连接并执行sql命令
    2. 删除数据库
    3. 重新创建数据库
    4. 打开到同一数据库的新连接,并尝试对其运行命令

    代码如下:

    using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=DBNAME;Integrated Security=True"))
    {
        conn.Open();
        var cmd = conn.CreateCommand();
        cmd.CommandText = "UPDATE ...";
        cmd.ExecuteNonQuery();
    }
    
    string sql = "Alter Database DBNAME set single_user with rollback immediate drop database DBNAME";
    var server = new Microsoft.SqlServer.Management.Smo.Server(".");
    server.ConnectionContext.ExecuteNonQuery(sql);
    server.ConnectionContext.Disconnect();
    
    sql = File.ReadAllText("PathToDotSqlFile..."));
    server = new Microsoft.SqlServer.Management.Smo.Server(".");
    server.ConnectionContext.ExecuteNonQuery(sql);
    server.ConnectionContext.Disconnect();
    
    using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=WER_CONFIG;Integrated Security=True"))
    {
        conn.Open();
        var cmd = conn.CreateCommand();
        cmd.CommandText = "UPDATE ...";
        cmd.ExecuteNonQuery();
    }
    

    错误发生在最后一行的“cmd.ExecuteNonQuery()”上。看起来,即使每次连接时我都在创建一个新连接,sql server仍在跟踪某个东西(或者可能是ADO.net代码),下次我请求连接时,它会给我一个已经在服务器端使用或已关闭的连接。直到您尝试对其执行另一个命令,它才意识到它已被服务器关闭(可能是因为它所连接的数据库被删除)。

    我还尝试使用外部进程删除并重新创建数据库,如下所示:

    ProcessStartInfo info = new ProcessStartInfo("sqlcmd.exe", " -e -E -S . -Q \"Alter Database DBNAME set single_user with rollback immediate drop database DBNAME\"");
    var p = Process.Start(info);
    p.WaitForExit();
    
    info = new ProcessStartInfo("sqlcmd.exe", " -i " + PathToDotSqlFile);
    p = Process.Start(info);
    p.WaitForExit();
    

    有没有办法创建一个新的SqlConnection并确保它是干净的,而不是从池中创建的?关于如何解决这个问题还有其他建议吗?

    2 回复  |  直到 16 年前
        1
  •  7
  •   Sven Künzler    16 年前

    ADO.NET自动管理连接池。当您“关闭”应用程序中的连接时,它将返回到池并保持活动状态,以防您请求具有相同连接字符串的连接。这可能是您的“新”连接过时的原因。

    您可以尝试通过添加 pooling=false 作为连接字符串的参数。

        2
  •  3
  •   Tomo    16 年前

    编辑:ADO.NET2.0似乎向SQLConnection对象添加了一个ClearPool函数。( http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool(VS.80).aspx )我很想知道这是否有效。