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

  

将请求发送到服务器时发生传输级错误。 (提供者:共享内存提供者,错误:0 - 管道的另一端没有进程。)

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

  

将请求发送到服务器时发生传输级错误。 (提供者:TCP提供者,错误:0 - 远程主机强行关闭现有连接。)

以下是重现问题的步骤:

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

    以下是代码:

    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并确保它是干净的而不是来自池?关于如何解决这个问题的任何其他建议?

    更新:使用SqlConnection.ClearPool()确实解决了问题,但我选择只使用pooling = false编辑我的连接字符串,这也有效。

有帮助吗?

解决方案

ADO.NET自动管理连接池。当你“关闭”时如果您使用相同的连接字符串请求连接,则应用程序中的连接将返回到池并保持活动状态。这可能是你的“新”的原因。连接陈旧。

您可以尝试通过将 pooling = false 作为参数添加到连接字符串来关闭此行为。

其他提示

不了解SQL2008,但这听起来像应用程序端的连接池问题。在过去,我们添加了“OLEDB Services = -1”。连接字符串以关闭连接池。现在可能有更优雅的方式来做到这一点。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top