2009-05-04 6 views
3

Ich habe Probleme mit SQL Server eine Verbindung fallen lassen, nachdem ich eine gegebene Datenbank gelöscht und neu erstellt habe und das nächste Mal versuche ich einen Befehl für eine neue Verbindung in der gleichen Datenbank auszuführen , erhalte ich:Sql Server 2008 Closing Connections nach Datenbank gelöscht

A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)

Hier ist die TCP-Version (Wenn ich versuche, auf einen anderen Server zu verbinden)

A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

Hier sind die Schritte, das Problem repro:

  1. Öffnen Sie eine Verbindung zu einer Datenbank und führen Sie eine SQL-Befehl
  2. Drop the Datenbank
  3. Re-Erstellen der Datenbank
  4. Öffnen Sie eine neue Verbindung zu derselben Datenbank und versuchen, einen Befehl dagegen
laufen

Ergebnis: Sie erhalten eine Ausnahme

Hier ist der Code ist:

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(); 
} 

Der Fehler tritt am Ende in der Zeile 'cmd.ExecuteNonQuery()' auf. Es scheint, dass, obwohl ich jedes Mal, wenn ich verbinde, eine neue Verbindung erstellen, sql Server verfolgt etwas (oder möglicherweise der ADO.net-Code), wo das nächste Mal, wenn ich nach einer Verbindung frage, gibt es mir eine, die bereits verwendet wird oder wurde auf der Serverseite geschlossen. Es merkt nicht, dass es vom Server geschlossen wurde (vermutlich wegen der Datenbank, mit der es gelöscht wurde), bis Sie versuchen, einen anderen Befehl dagegen auszuführen.

Beachten Sie, dass ich diesen Fehler nicht erhalte, wenn ich den ersten Schritt der Ausführung der ersten Abfrage nicht mache, und ich nur die Datenbank löschen, neu erstellen und einen Befehl ausführen. Ich denke, dass das Einrichten dieser ersten Verbindung, bevor die Datenbank gelöscht wird, ein wichtiger Teil dieses Fehlers ist.

Ich habe auch einen externen Prozess mit löschen und neu erstellen die Datenbank wie so versucht:

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(); 

Und das half nicht.

Gibt es eine Möglichkeit, eine neue SqlConnection zu erstellen und sicherzustellen, dass sie sauber ist und nicht aus einem Pool? Irgendwelche anderen Vorschläge, wie man dieses Problem löst?

UPDATE: Die Verwendung von SqlConnection.ClearPool() löste das Problem, aber ich entschied mich, nur meine Verbindungszeichenfolge mit pooling = false zu bearbeiten, was auch funktionierte.

Antwort

7

ADO.NET verwaltet automatisch einen Verbindungspool.Wenn Sie eine Verbindung in Ihrer Anwendung "schließen", wird sie an den Pool zurückgegeben und am Leben gehalten, falls Sie eine Verbindung mit derselben Verbindungszeichenfolge anfordern. Dies könnte der Grund sein, warum Ihre "neue" Verbindung veraltet ist.

Sie können versuchen, dieses Verhalten zu deaktivieren, indem Sie Ihrer Verbindungszeichenfolge pooling=false als Parameter hinzufügen.

3

Ich weiß nichts über SQL2008, aber das klingt wie ein Verbindungspooling-Problem auf der Anwendungsseite. In den alten Tagen haben wir der Verbindungszeichenfolge "OLEDB Services = -1" hinzugefügt, um das Verbindungspooling zu deaktivieren. Es gibt wahrscheinlich einen eleganteren Weg, dies jetzt zu tun.

edit: ADO.Net 2.0 scheint dem SQLConnection-Objekt eine ClearPool-Funktion hinzugefügt zu haben. (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool(VS.80).aspx) Ich bin sehr interessiert zu wissen, ob das funktioniert.