Warum so viele sp_resetconnections für C # Connection Pooling?

8

Wir haben einen in C # codierten Web-Service, der viele Aufrufe der MS SQL Server 2005-Datenbank aufruft. Der Code verwendet die Verwendung von Blöcken, die mit dem Verbindungs-Pooling von C # kombiniert werden.

Während einer SQL-Ablaufverfolgung haben wir viele, viele Aufrufe von "sp_resetconnection" gesehen. Die meisten davon sind kurz & lt; 0,5 Sekunden, aber manchmal bekommen wir Anrufe, die bis zu 9 Sekunden dauern.

Nach dem, was ich gelesen habe, ist sp_resetconnection mit dem Verbindungspooling verbunden und setzt grundsätzlich den Zustand einer offenen Verbindung zurück. Meine Fragen:

  • Warum muss eine offene Verbindung ihren Status zurücksetzen?
  • Warum so viele dieser Anrufe!
  • Was dazu führen könnte, dass ein Aufruf der sp_reset-Verbindung eine nicht unerhebliche Zeit in Anspruch nimmt.

Das ist ziemlich das Mysterium für mich, und ich schätze jede und jede Hilfe!

    
Zugwalt 07.06.2009, 17:13
quelle

4 Antworten

12

Durch das Zurücksetzen werden die Dinge einfach zurückgesetzt, sodass Sie sie nicht mehr zurücksetzen müssen, um sie zurückzusetzen. Es löscht die Verbindung sauber von Dingen wie SET oder USE-Operationen, so dass jede Abfrage eine saubere Weste hat.

Die Verbindung wird immer noch verwendet. Hier ist eine umfangreiche Liste :

sp_reset_connection setzt die folgenden Aspekte einer Verbindung zurück:

  • Es setzt alle Fehlerzustände und -zahlen zurück (wie @@ error)
  • Es stoppt alle ECs (Ausführungskontexte), die Kind-Threads eines Eltern-ECs sind, die eine parallele Abfrage ausführen
  • Es wird auf ausstehende E / A-Vorgänge, die ausstehen, gewartet
  • Es werden alle gehaltenen Puffer auf dem Server durch die Verbindung
  • freigegeben
  • Es werden alle Pufferressourcen freigegeben, die von der Verbindung verwendet werden
  • Es wird der gesamte Speicher freigegeben, der der Verbindung zugeordnet ist
  • Es löscht alle Arbeit oder temporäre Tabellen, die durch die Verbindung erstellt werden
  • Es werden alle globalen Cursor der Verbindung gelöscht
  • Es schließt alle offenen SQL-XML-Handles, die geöffnet sind
  • Es werden alle offenen SQL-XML-bezogenen Arbeitstabellen gelöscht
  • Es schließt alle Systemtabellen
  • Es schließt alle Benutzertabellen
  • Es werden alle temporären Objekte gelöscht
  • Es werden offene Transaktionen abgebrochen
  • Bei einer verteilten Transaktion wird ein Fehler auftreten, wenn
  • eingetragen wird
  • Es wird die Referenzanzahl für Benutzer in der aktuellen Datenbank verringert; welche freigegebene Datenbanksperre freigeben
  • Es wird die erworbenen Sperren freigeben
  • Es werden alle Griffe freigegeben, die möglicherweise erworben wurden
  • Dadurch werden alle SET-Optionen auf die Standardwerte
  • zurückgesetzt
  • Dadurch wird der @@ rowcount-Wert
  • zurückgesetzt
  • Es wird der @@ Identity-Wert
  • zurückgesetzt
  • Es werden alle Ablaufverfolgungsoptionen auf Sitzungsebene mit dbcc traceon ()
  • zurückgesetzt

sp_reset_connection wird NICHT zurückgesetzt:

  • Sicherheitskontext, weshalb das Verbindungspooling Verbindungen basierend auf der genauen Verbindungszeichenfolge
  • abgleicht
  • Wenn Sie eine Anwendungsrolle mit sp_setapprole eingegeben haben, da Anwendungsrollen nicht zurückgesetzt werden können
  • Die Transaktionsisolationsstufe (!)
Michael Haren 07.06.2009, 17:15
quelle
1

Hier ist eine Erklärung von Was macht sp_reset_connection? , die teilweise "Data Access API" -Schichten wie ODBC sagt , OLE-DB und SqlClient rufen die (interne) gespeicherte Prozedur sp_reset_connection auf, wenn sie eine Verbindung aus einem Verbindungspool wiederverwenden. Dadurch wird der Zustand der Verbindung zurückgesetzt, bevor sie wieder verwendet wird. " Dann gibt es einige Besonderheiten dessen, was dieses System tut. Es ist eine gute Sache.

    
DOK 07.06.2009 17:24
quelle
1

sp_resetconnection wird jedes Mal aufgerufen, wenn Sie eine neue Verbindung von einem Pool anfordern. Es muss dies tun, da der Pool den Benutzer nicht garantieren kann (Sie, der Programmierer wahrscheinlich :) haben die Verbindung in einem ordnungsgemäßen Zustand verlassen. z.B. Die Rückgabe einer alten Verbindung mit nicht übergebenen Transaktionen wäre ... schlecht.

Die Anzahl der Anrufe sollte sich auf die Anzahl der Zeiten beziehen, zu denen Sie eine neue Verbindung erhalten.

Was einige Anrufe angeht, die nicht trivial sind, bin ich mir nicht sicher. Könnte sein, dass der Server gerade sehr beschäftigt ist, andere Sachen zu dieser Zeit zu verarbeiten. Könnte Netzwerkverzögerungen sein.

    
nos 07.06.2009 17:40
quelle
1

Grundsätzlich sind die Anrufe die Statusinformationen zum Löschen. Wenn Sie irgendwelche offenen DataReader haben, wird es viel länger dauern. Dies liegt daran, dass Ihre DataReader nur eine einzelne Zeile enthalten, aber mehr Zeilen ziehen können. Sie müssen jeweils gelöscht werden, bevor das Zurücksetzen fortgesetzt werden kann. Stellen Sie also sicher, dass Sie alles mit () -Anweisungen haben, und lassen Sie einige Dinge in einigen Ihrer Aussagen nicht offen.

Wie viele Verbindungen haben Sie, wenn das passiert?

Wenn Sie maximal 5 haben und alle 5 drücken, wird das Zurücksetzen blockiert - und es wird lange dauern. Es ist wirklich nicht, es ist nur blockiert warten auf eine gepoolte Verbindung verfügbar zu sein.

Auch wenn Sie mit SQL Express arbeiten, können Sie aufgrund von Threading-Anforderungen sehr leicht blockiert werden (könnte auch in vollem SQL Server passieren, aber viel weniger wahrscheinlich).

Was passiert, wenn Sie das Verbindungs-Pooling deaktivieren?

    
Jason Short 09.06.2009 21:14
quelle