Luk*_*ust 3 .net c# sql sql-server sql-server-2008
在删除并重新创建给定数据库之后,我遇到SQL Server丢弃连接的问题,下次当我尝试对同一个数据库上的新连接执行命令时,我得到:
将请求发送到服务器时发生传输级错误.(提供者:共享内存提供者,错误:0 - 管道的另一端没有进程.)
这是TCP版本(如果我尝试连接到另一台服务器)
将请求发送到服务器时发生传输级错误.(提供程序:TCP提供程序,错误:0 - 远程主机强制关闭现有连接.)
以下是重现问题的步骤:
结果:我收到一个例外
这是代码:
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();
}
Run Code Online (Sandbox Code Playgroud)
错误发生在最后的'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();
Run Code Online (Sandbox Code Playgroud)
这没有帮助.
有没有办法创建一个新的SqlConnection并确保它是干净的而不是从池?关于如何解决这个问题的任何其他建议?
更新:使用SqlConnection.ClearPool()确实解决了问题,但我选择只使用pooling = false编辑我的连接字符串,这也有效.
ADO.NET自动管理连接池.当您"关闭"应用程序中的连接时,如果您使用相同的连接字符串请求连接,它将返回到池并保持活动状态.这可能是您的"新"连接过时的原因.
您可以尝试通过pooling=false在连接字符串中添加as参数来关闭此行为.