284 Stimmen

Wie kann ich ein Verbindungspoolproblem zwischen ASP.NET und SQL Server lösen?

In den letzten Tagen sehen wir diese Fehlermeldung zu oft auf unserer Website:

"Zeitüberschreitung abgelaufen. Die Timeout-Periode verstrichen, bevor eine Verbindung Verbindung aus dem Pool zu erhalten. Dies kann aufgetreten sein, weil alle gepoolten Verbindungen verwendet wurden und die maximale Pool Größe erreicht wurde."

Wir haben seit einiger Zeit nichts mehr an unserem Code geändert. Ich habe den Code überarbeitet, um offene Verbindungen zu überprüfen, die nicht geschlossen wurden, aber alles war in Ordnung.

  • Wie kann ich das Problem lösen?

  • Muss ich diesen Pool bearbeiten?

  • Wie kann ich die maximale Anzahl der Verbindungen für diesen Pool bearbeiten?

  • Was ist der empfohlene Wert für eine stark frequentierte Website?


Aktualisierung:

Muss ich etwas im IIS bearbeiten?

Aktualisierung:

Ich fand, dass die Anzahl der aktiven Verbindungen überall von 15 bis 31 sind, und ich fand, dass die maximal zulässige Anzahl von Verbindungen in SQL Server konfiguriert ist mehr als 3200 Verbindungen, ist 31 zu viele oder sollte ich etwas in der ASP.NET-Konfigration bearbeiten?

279voto

splattne Punkte 102178

In den meisten Fällen hängen Probleme mit dem Pooling von Verbindungen zusammen mit Verbindungslecks . Ihre Anwendung schließt ihre Datenbankverbindungen wahrscheinlich nicht korrekt und konsequent. Wenn Sie Verbindungen offen lassen, bleiben sie blockiert, bis der .NET Garbage Collector sie für Sie schließt, indem er ihre Finalize() Methode.

Sie möchten sicherstellen, dass Sie die Verbindung wirklich zu schließen . Der folgende Code verursacht beispielsweise ein Verbindungsleck, wenn der Code zwischen .Open y Close eine Ausnahme auslöst:

var connection = new SqlConnection(connectionString);

connection.Open();
// some code
connection.Close();                

Der richtige Weg wäre der folgende:

var connection = new SqlConnection(ConnectionString);

try
{
     connection.Open();
     someCall (connection);
}
finally
{
     connection.Close();                
}

oder

using (SqlConnection connection = new SqlConnection(connectionString))
{
     connection.Open();
     someCall(connection);
}

Wenn Ihre Funktion gibt eine Verbindung aus einer Klassenmethode zurück stellen Sie sicher, dass Sie sie lokal zwischenspeichern und ihre Close Methode. Mit diesem Code können Sie zum Beispiel eine Verbindung unterbrechen:

var command = new OleDbCommand(someUpdateQuery, getConnection());

result = command.ExecuteNonQuery();
connection().Close(); 

Die Verbindung, die beim ersten Aufruf von getConnection() wird nicht geschlossen. Anstatt Ihre Verbindung zu schließen, erstellt diese Zeile eine neue und versucht, sie zu schließen.

Wenn Sie SqlDataReader oder eine OleDbDataReader schließen Sie sie. Auch wenn das Schließen der Verbindung selbst zu funktionieren scheint, sollten Sie sich die Mühe machen, Ihre Datenleseobjekte explizit zu schließen, wenn Sie sie verwenden.


Dieser Artikel " Warum läuft ein Verbindungspool über? " aus dem MSDN/SQL Magazine erklärt viele Details und schlägt einige Debugging-Strategien vor:

  • Exécuter sp_who o sp_who2 . Diese gespeicherten Systemprozeduren geben Informationen aus dem sysprocesses Systemtabelle, die den Status und Informationen über alle Arbeitsprozesse anzeigt. Im Allgemeinen sehen Sie eine Server-Prozess-ID (SPID) pro Verbindung. Wenn Sie Ihre Verbindung mit dem Argument Anwendungsname in der Verbindungszeichenfolge benannt haben, sind Ihre funktionierenden Verbindungen leicht zu finden.
  • Verwendung des SQL Server Profiler mit dem SQLProfiler TSQL_Replay Vorlage, um offene Verbindungen zu verfolgen. Wenn Sie mit Profiler vertraut sind, ist diese Methode einfacher als das Polling mit sp_who.
  • Verwenden Sie den Performance Monitor, um die Pools und Verbindungen zu überwachen. Auf diese Methode werde ich gleich noch eingehen.
  • Leistungszähler im Code überwachen. Sie können den Zustand Ihres Verbindungspools und die Anzahl der hergestellten Verbindungen überwachen, indem Sie Routinen zum Extrahieren der Zähler oder die neuen .NET PerformanceCounter-Steuerelemente verwenden.

52voto

ajbeaven Punkte 8838

Nach der Installation von .NET Framework v4.6.1 fingen unsere Verbindungen zu einer entfernten Datenbank sofort an, sich zu verzögern aufgrund dieser Änderung .

Zur Korrektur fügen Sie einfach den Parameter TransparentNetworkIPResolution in der Verbindungszeichenfolge und setzen Sie sie auf falsch :

Server=meinServerName;Datenbank=meineDatenbank;Vertrauenswürdige_Verbindung=True; TransparentNetworkIPResolution=False

15voto

Ivo Punkte 3333

Haben Sie auf nicht geschlossene DataReader und response.redirects geprüft, bevor Sie die Verbindung oder einen Datareader schließen. Verbindungen bleiben offen, wenn Sie sie nicht vor einer Weiterleitung schließen.

15voto

Marc Gravell Punkte 970173

Wenn Ihre Nutzung nicht stark gestiegen ist, ist es unwahrscheinlich, dass es nur einen Arbeitsrückstand gibt. IMO ist die wahrscheinlichste Option, dass irgendetwas Verbindungen nutzt und sie nicht rechtzeitig freigibt. Sind Sie sicher Sie verwenden using in allen Fällen? Oder (durch welchen Mechanismus auch immer) die Freigabe der Verbindungen?

13voto

Ka_Ya Punkte 123

Sie können dies auch versuchen, um das Timeout-Problem zu lösen:

Wenn Sie httpRuntime nicht zu Ihrer Webconfig hinzugefügt haben, fügen Sie dies in <system.web> Tag

<sytem.web>
     <httpRuntime maxRequestLength="20000" executionTimeout="999999"/>
</system.web>

und

Ändern Sie Ihre Verbindungszeichenfolge wie folgt;

 <add name="connstring" connectionString="Data Source=DSourceName;Initial Catalog=DBName;Integrated Security=True;Max Pool Size=50000;Pooling=True;" providerName="System.Data.SqlClient" />

Zuletzt verwenden

    try
    {...} 
    catch
    {...} 
    finaly
    {
     connection.close();
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X