Vor ein paar Tagen hat mich ein alter Freund beim Tässchen Kaffee nochmals auf die Bugs eines gemeinsamen Projektes hingewiesen. Sachen, die Anfangs nie problematisch schienen, fliegen einem später schnell um die Ohren, so auch der verschwenderische Umgang mit SqlConnections.
Besonders während der Entwicklung fällt es nicht weiter auf, wenn die ein oder andere SqlConnection offen links liegen bleibt. - Keiner merkt es. Doch später, wenn die Anwendung erstmal richtig unter Dampf steht, kommt es zu ganz hässlichen Abstürzen: SqlTimeouts. Irgendwann kommt der Moment in dem ADO.NET keine Verbindung mehr öffnen kann - alle belegt.
Sofortmaßnahmen sind gefragt: Connection-Pool hochdrehen, sofort! Wie lautet der Eintrag für unendliche Verbindungen? Schnell!! Gibts nicht? Okay - 5.000 reichen erstmal.
Als nächstes steht eine Menge Reengineering auf dem Plan: jeden Aufruf kontrollieren und dafür sorgen, dass die Connection zeitnah wieder geschlossen wird. Oh nein, die Anwendung ist aber langsam geworden! Ja, aber dafür stützt sie nicht mehr ab ....
Ein zeitiger Lasttest hätte diesen Fehler früher zu Tage gebracht, auch im letzten Projekt brachte er uns zahlreiche, vergessene SqlConnections und weitere Multi-User Probleme auf den Tisch. Besser da, als im Produktivbetrieb ...
Ein paar Gedanken zum Schluss:
- Connections so kurz wie möglich offen halten
- Ein Connection.Close() gibt Ressourcen im Pool frei, nicht direkt auf dem Sql Server (geht also eigentlich recht fix)
- Trotz Pool ist eine ständige, offene Verbindung schneller. Trotzdem: lohnt nicht, s.o.
- Mit using gegen den inneren Schweinehund angehen
using (SqlConnection conn = MyDB.GetConnection()){
...Statements...
} - Verbindungen mit Performance-Monitor überwachen
- Eine Anwendung verhält sich zur Laufzeit anders, als zur Entwicklung - Multi User, nie vergessen!!