Jak mogę rozwiązać problem z pulą połączeń między ASP.NET a SQL Server?

W ciągu ostatnich kilku dni widzimy ten Komunikat o błędzie na naszej stronie zbyt dużo:

" Timeout minął. Okres przedawnienia upłynął przed uzyskaniem połączenie z basenu. To może miały miejsce, ponieważ wszystkie zebrane połączenia były w użyciu, a maksymalna Pula Rozmiar został osiągnięty."

Od jakiegoś czasu nic nie zmieniliśmy w naszym kodzie. Zmieniłem kod, aby sprawdzić otwarte połączenia, które nie zamykały się, ale okazało się, że wszystko jest w porządku.

  • Jak mogę rozwiązać?

  • Czy muszę edytować ten Basen?

  • Jak mogę edytować maksymalną liczbę połączeń tej puli?

  • Jaka jest zalecana wartość dla strony o dużym natężeniu ruchu?


Aktualizacja:

Czy muszę coś edytować w IIS?

Aktualizacja:

Odkryłem, że liczba aktywnych połączeń wynosi od 15 do 31, i odkryłem, że maksymalna dozwolona liczba połączeń skonfigurowanych w SQL server jest większa niż 3200 połączeń, jest o 31 za dużo czy powinienem coś edytować w ASP.NET konfiguracja?

Author: GEOCHET, 2009-03-22

17 answers

W większości przypadków problemy z łącznością są związane z " wyciekami połączenia."Twoja aplikacja prawdopodobnie nie zamyka poprawnie i konsekwentnie połączeń z bazą danych. Po pozostawieniu połączeń otwartych, pozostają one zablokowane do momentu zamknięcia ich przez.Net garbage collector przez wywołanie ich metody Finalize().

Chcesz się upewnić, że naprawdę zamykasz połączenie. Na przykład poniższy kod spowoduje wyciek połączenia, jeśli kod pomiędzy .Open i Close rzuca wyjątek:

var connection = new SqlConnection(connectionString);
connection.Open();
// some code
connection.Close();                

Poprawny sposób byłby taki:

var connection = new SqlConnection(ConnectionString);
try
{
     connection.Open();
     someCall (connection);
}
finally
{
     connection.Close();                
}

Lub

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

Gdy twoja funkcja zwróci połączenie z metody klasy upewnij się, że buforujesz je lokalnie i wywołujesz jej metodę Close. W ten sposób można na przykład wykasować połączenie za pomocą tego kodu:

var command = new OleDbCommand(someUpdateQuery, getConnection());
result = command.ExecuteNonQuery();
connection().Close(); 

Połączenie zwrócone Od pierwszego wywołania do {[8] } nie jest zamykane. Zamiast zamykać połączenie, linia ta tworzy nowe i próbuje zamknąć to.

Jeśli używasz SqlDataReader lub OleDbDataReader, zamknij je. Nawet jeśli zamknięcie samego połączenia wydaje się robić sztuczkę, włożyć w dodatkowy wysiłek, aby zamknąć obiekty czytnika danych bezpośrednio podczas ich używania.


Ten artykuł " dlaczego przepełnia się Pula połączeń?[36]}" z magazynu MSDN / SQL wyjaśnia wiele szczegółów i sugeruje pewne strategie debugowania: [16]}

 163
Author: splattne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-06 12:57:27

Po zainstalowaniu.NET Framework v4.6.1 nasze połączenia ze zdalną bazą danych natychmiast zaczęły wygasać z powodu tej zmiany.

Aby naprawić, wystarczy dodać parametr TransparentNetworkIPResolution w łańcuchu połączeń i ustawić go na false :

Server=myServerName;Database=myDataBase;Trusted_Connection=True;TransparentNetworkIPResolution=False

 24
Author: ajbeaven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-10 11:49:58

Chyba że Twoje użycie poszło dużo, wydaje się mało prawdopodobne, że jest tylko zaległości w pracy. IMO najbardziej prawdopodobną opcją jest to, że coś używa połączeń i nie zwalnia ich natychmiast. Czy jesteś pewien, że używasz we wszystkich przypadkach? Lub (przez jakikolwiek mechanizm) uwalnianie połączeń?

 12
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-22 09:58:39

Czy sprawdziliście czy nie są zamknięte i odpowiedzi.przekierowuje przed zamknięciem połączenia lub czytnika danych. Połączenia pozostają otwarte, gdy nie zamkniesz ich przed przekierowaniem.

 11
Author: Ivo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-22 10:05:28

Od czasu do czasu spotykamy się z tym problemem również na naszej stronie internetowej. Winowajcą w naszym przypadku jest to, że nasze statystyki/indeksy nie są aktualne. Powoduje to, że wcześniej szybko uruchomione zapytanie (ostatecznie) staje się powolne i upływa czas.

Spróbuj zaktualizować statystyki i / lub przebudować indeksy tabel, których dotyczy zapytanie, i sprawdź, czy to pomaga.

 9
Author: Alex Czarto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-14 22:51:42

Możesz określić minimalny i maksymalny rozmiar puli poprzez podanie MinPoolSize=xyz i / lub MaxPoolSize=xyz w łańcuchu połączenia. Ta przyczyna problemu może być jednak inna.

 5
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-22 09:53:55

Napotkałem również ten problem, gdy używałem warstwy danych innej firmy w jednej z moich aplikacji. NET. Problem polegał na tym, że warstwa nie zamykała prawidłowo połączeń.

Wyrzuciliśmy warstwę i stworzyliśmy ją sami, która zawsze zamyka się i usuwa połączenia. Od tego czasu nie dostajemy już błędu.

 5
Author: Wim Haanstra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-22 10:50:46

Jeśli pracujesz na złożonym kodzie legacy, gdzie proste użycie(..) {..} nie jest możliwe - tak jak ja-możesz sprawdzić fragment kodu, który zamieściłem w tym , więc pytanie o sposób określenia stosu wywołań tworzenia połączenia, gdy połączenie jest potencjalnie wyciekłe(nie zamknięte po określonym czasie). To sprawia, że dość łatwo dostrzec przyczynę wycieków.

 2
Author: LOAS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:33

Wynika to głównie z tego, że połączenie nie zostało zamknięte w aplikacji. Użyj "MinPoolSize" i "MaxPoolSize" w łańcuchu połączeń.

 2
Author: subramanian.m,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-31 05:57:59

W moim przypadku nie zamykałem obiektu DataReader.

        using (SqlCommand dbCmd = new SqlCommand("*StoredProcedureName*"))
        using (dbCmd.Connection = new SqlConnection(WebConfigurationAccess.ConnectionString))
            {
            dbCmd.CommandType = CommandType.StoredProcedure;

            //Add parametres
            dbCmd.Parameters.Add(new SqlParameter("@ID", SqlDbType.Int)).Value = ID;
.....
.....
            dbCmd.Connection.Open();
            var dr = dbCmd.ExecuteReader(); //created a Data reader here
            dr.Close();    //gotta close the data reader
            //dbCmd.Connection.Close(); //don't need this as 'using' statement should take care of this in its implicit dispose method.
            }
 2
Author: DevelopZen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-24 15:31:37

Nie uruchamiaj połączenia sql zbyt wiele razy. Otwórz jedno lub dwa połączenia i użyj ich do wszystkich kolejnych operacji sql.

Wydaje się, że nawet gdy DisposeING połączenia wyjątek jest wyrzucany.

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-13 10:39:08

Użyj tego:

finally
{
    connection.Close();
    connection.Dispose();
    SqlConnection.ClearPool();
}
 2
Author: Jeno M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 10:50:18

Możesz też spróbować, aby rozwiązać problem z limitem czasu:

Jeśli nie dodałeś httpRuntime do swojego webconfig, dodaj to w znaczniku <system.web>
<sytem.web>
     <httpRuntime maxRequestLength="20000" executionTimeout="999999"/>
</system.web>

I

Zmodyfikuj łańcuch połączeń w ten sposób;

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

At last use

    try
    {...} 
    catch
    {...} 
    finaly
    {
     connection.close();
    }
 2
Author: Ka_Ya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-02 14:37:14

Ten problem miałem w kodzie. Wkleję przykładowy kod, który przekroczyłem, poniżej błąd. czas oczekiwania upłynął przed uzyskaniem połączenia z puli. Mogło się to zdarzyć, ponieważ wszystkie połączenia z pulą były używane i osiągnięto maksymalny rozmiar puli.

 String query = "insert into STATION2(ID,CITY,STATE,LAT_N,LONG_W) values('" + a1 + "','" + b1 + "','" + c1 + "','" + d1 + "','" + f1 + "')";
    //,'" + d1 + "','" + f1 + "','" + g1 + "'

    SqlConnection con = new SqlConnection(mycon);
    con.Open();
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = query;
    cmd.Connection = con;
    cmd.ExecuteNonQuery();
    **con.Close();**
Chcesz zamknąć połączenie za każdym razem. Wcześniej nie byłem blisko połączenia z tego powodu dostałem błąd. Po dodaniu close statement mam nad przyszedł ten błąd
 1
Author: Aravindhan R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-18 11:41:30

Oprócz zamieszczonych rozwiązań....

W radzeniu sobie z 1000 stronami kodu starszego, z których każda wywołuje wspólny GetRS wiele razy, oto inny sposób na rozwiązanie problemu:

W istniejącym common DLL, dodaliśmy CommandBehavior.Closeconnection Opcja:

    static public IDataReader GetRS(String Sql)
    {
        SqlConnection dbconn = new SqlConnection(DB.GetDBConn());
        dbconn.Open();
        SqlCommand cmd = new SqlCommand(Sql, dbconn);
        return cmd.ExecuteReader(CommandBehavior.CloseConnection);   
    }

Następnie na każdej stronie, tak długo, jak zamkniesz czytnik danych, połączenie jest również automatycznie zamykane, aby zapobiec wyciekom połączenia.

    IDataReader rs = CommonDLL.GetRS("select * from table");
    while (rs.Read())
    {
        // do something
    }
    rs.Close();   // this also closes the connection
 1
Author: David Nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-31 05:32:46

Masz przeciekające połączenia w swoim kodzie. Możesz spróbować użyć using, aby potwierdzić, że je zamykasz.

 Using (SqlConnection sqlconnection1 = new SqlConnection(“Server=.\\SQLEXPRESS ;Integrated security=sspi;connection timeout=5”)) {
                          sqlconnection1.Open();
                          SqlCommand sqlcommand1 = sqlconnection1.CreateCommand();
                          sqlcommand1.CommandText = “raiserror (‘This is a fake exception’, 17,1)”;
                          sqlcommand1.ExecuteNonQuery();  //this throws a SqlException every time it is called.
                          sqlconnection1.Close(); //Still never gets called.
              } // Here sqlconnection1.Dispose is _guaranteed_

Https://blogs.msdn.microsoft.com/angelsb/2004/08/25/connection-pooling-and-the-timeout-expired-exception-faq/

 0
Author: EduLopez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-15 13:14:35

Ten problem napotkałem już wcześniej. Skończyło się na problemie z firewallem. Właśnie dodałem regułę do Firewalla. Musiałem otworzyć port 1433, aby serwer SQL mógł się połączyć z serwerem.

 0
Author: Feisal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 20:37:50