wake-up-neo.com

Wie erzwinge ich das physische Schließen einer SqlConnection, während ich ein Verbindungspooling verwende?

Wenn ich ein SqlConnection-Objekt instanziiere, greife ich nach einer Verbindung aus einem Verbindungspool. Wenn ich Open () aufrufe, wird die Verbindung geöffnet. Wenn ich die Methode Close () oder Dispose () für dieses SqlConnection-Objekt aufrufe, wird es an den Verbindungspool zurückgegeben.

Das sagt mir jedoch nicht wirklich, ob es wirklich geschlossen ist oder ob ich noch eine aktive Verbindung zur Datenbank habe.

Wie kann ich erzwingen, dass eine SqlConnection auf Netzwerkebene geschlossen wird, oder zumindest feststellen, wann sie geschlossen wird?

Beispiel:

using(SqlConnection conn = new SqlConnection(DBConnString)) {

   conn.Open();
   SqlCommand cmd = conn.CreateCommand();
   ...
   cmd.ExecuteReader(CommandBehavior.CloseConnection);
   ...
}
  • Erster Lauf: 300 ms
  • Zweiter Lauf: 100 ms
  • Dritter Lauf: 100 ms
  • Nach langem Warten (30 Minuten): 300 ms

Wenn die Verbindung WIRKLICH geschlossen wurde, sollten der zweite und dritte Lauf ebenfalls 300 ms betragen. Aber ich weiß, dass die Verbindung für diese Läufe nicht wirklich geschlossen ist (ich habe die Aktivitätsüberwachung des SQL Servers überprüft). Es dauert keine zusätzlichen 200 ms, um die Authentifizierung durchzuführen.

Wie erzwinge ich, dass die Verbindung wirklich geschlossen wird?

Ideen

  • Funktioniert CommandBehavior.CloseConnection? (scheinbar nicht?)
  • Funktioniert die Einstellung "Max Pool Size = 0" in der Verbindungszeichenfolge? (Dies wäre eine pyrrhische Lösung)
  • Funktioniert Dispose ()?

Referenzen

36
51
Moe Sisko

Moe Siskos Antwort (Call SqlConnection.ClearPool) ist korrekt.

Manchmal benötigen Sie eine Verbindung, um wirklich geschlossen zu werden, anstatt zum Pool zurückzukehren. Als Beispiel habe ich einen Unit-Test, der eine Scratch-Datenbank erstellt, das Schema erstellt, etwas testet und dann die Scratch-Datenbank löscht, wenn alle Tests erfolgreich sind.

Wenn das Verbindungspooling aktiv ist, schlägt der Befehl drop database fehl, da noch aktive Verbindungen vorhanden sind. Aus Sicht des Programmierers sind alle SQLConnections geschlossen, aber da der Pool noch eine geöffnet hat, lässt SQL Server das Löschen nicht zu.

Die beste Dokumentation für die Behandlung von Verbindungspools ist diese Seite in SQL Server Connection Pooling in MSDN. Sie möchten das Verbindungs-Pooling nicht vollständig deaktivieren, da es durch wiederholtes Öffnen und Schließen die Leistung verbessert. In manchen Fällen müssen Sie jedoch eine "Zwangsschließung" für eine SQLConnection aufrufen, damit die Datenbank freigegeben wird. 

Dies erfolgt mit ClearPool. Wenn Sie SqlConnection.ClearPool(connection) vor dem Schließen/Entsorgen aufrufen, wird das Schließen und Entsorgen des Ordners wirklich verschwinden.

24
Robert Calhoun

Wenn Sie den Verbindungspool nicht verwenden möchten, müssen Sie ihn in Ihrer SqlConnection.ConnectionString-Eigenschaft angeben. Zum Beispiel

"Data Source=MSSQL1;Database=AdventureWorks;Integrated Security=true;Pooling=false;"

Beim Entsorgen oder Schließen des SqlConnection-Objekts wird die Verbindung einfach geschlossen und an den Verbindungspool zurückgegeben.

9
ZippyV

Im Allgemeinen soll der Verbindungspool seine Aufgabe erfüllen - die Verbindung sollte nicht wirklich geschlossen werden.

Warum soll die Verbindung nicht speziell zum Pool zurückkehren?

3
Eamon Nerbonne

Ich sehe, dass Sie .net verwenden, aber da dies in einer Google-Abfrage angezeigt wurde, können Sie eine Java-Antwort geben ...

Verwenden Sie eine DataSource, die Closeable () implementiert, und rufen Sie close für die DataSource auf. Hikari unterstützt Closeable.

0
user939857