Comment puis-je résoudre un problème de piscine de connexion entre ASP.NET et SQL Server?

ces derniers jours, nous avons vu ce message d'erreur sur notre site Web trop:

"Délai d'attente expiré. La période de temps mort s'est écoulé avant l'obtention d'un connexion depuis la piscine. Cela peut ont eu lieu parce que tous les les connexions étaient en usage et Max pool la taille a été atteint."

nous n'avons rien changé dans notre code depuis un moment. J'ai révisé le code pour vérifier les connexions ouvertes qui n'ont pas fermé, mais j'ai trouvé tout pour être bien.

  • comment résoudre ce problème?

  • Dois-je modifier cette piscine?

  • Comment puis-je modifier le nombre maximum de connexions de cette piscine?

  • Quelle est la valeur recommandée pour un site web très fréquenté?


mise à jour:

est-ce que je dois éditer quelque chose dans IIS?

mise à jour:

j'ai trouvé que le nombre de connexions actives sont n'importe où de 15 à 31, et j'ai trouvé que le nombre maximum autorisé de connexions configurées dans le serveur SQL est plus de 3200 connexions, est 31 de trop ou devrais-je éditer quelque chose dans le ASP.NET le config nement?

150
demandé sur GEOCHET 2009-03-22 12:50:47

17 réponses

dans la plupart des cas, les problèmes de mise en commun des connexions sont liés à des fuites de connexion."Votre application ne ferme probablement pas ses connexions de base de données correctement et systématiquement. Lorsque vous laissez les connexions ouvertes, elles restent bloquées jusqu'à ce que le ramasseur D'ordures .NET les ferme pour vous en appelant leur méthode Finalize() .

vous voulez Vous assurer que vous êtes vraiment la fermeture de la connexion . Par exemple, le code suivant provoque une fuite de connexion, si le code entre .Open et Close jette une exception:

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

la bonne façon serait celle-ci:

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

ou

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

lorsque votre fonction renvoie une connexion à partir d'une méthode de classe assurez-vous de la mettre en cache localement et d'appeler sa méthode Close . Vous perdrez une connexion en utilisant ce code par exemple:

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

la connexion revenue du premier appel à getConnection() n'est pas fermée. Au lieu de fermer votre connexion, cette ligne crée une nouvelle et essaie de la fermer.

si vous utilisez SqlDataReader ou un OleDbDataReader , fermez-les. Même si fermer la connexion elle-même semble faire l'affaire, mettez l'effort supplémentaire de fermer vos objets de lecteur de données explicitement lorsque vous les utilisez.


cet article " pourquoi une piscine de connexion déborde-t-elle? " à partir de MSDN/SQL Magazine explique beaucoup de détails, et suggère des stratégies de débogage:

  • Exécuter sp_who ou sp_who2 . Ces procédures stockées dans le système renvoient des informations de la table système sysprocesses qui montre l'état et les informations de tous les processus de travail. Généralement, vous verrez un identifiant de processus de serveur (SPID) par connexion. Si vous avez nommé votre connexion en utilisant l'argument nom D'Application dans la chaîne de connexion, vos connexions de travail seront faciles à trouver.
  • utilisez SQL Server Profiler avec le modèle TSQL_Replay pour tracer les connexions ouvertes. Si vous êtes familier avec Profiler, cette méthode est plus facile que polling en utilisant sp_who.
  • utilisez le moniteur de Performance pour surveiller les piscines et les connexions. Je discuter de cette méthode dans un instant.
  • compteurs de performances des moniteurs dans le code. Vous pouvez surveiller la santé de votre pool de connexions et le nombre de connexions établies en utilisant des routines pour extraire les compteurs ou en utilisant les nouveaux contrôles.net PerformanceCounter.
163
répondu splattne 2015-12-06 12:57:27

lors de l'installation de .net Framework v4.6.1 Nos connexions à une base de données distante ont immédiatement commencé à chronométrer en raison de ce changement .

pour fixer il suffit d'ajouter le paramètre TransparentNetworkIPResolution dans la chaîne de connexion et de le définir à false :

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

24
répondu ajbeaven 2018-05-10 11:49:58

à moins que votre utilisation a augmenté beaucoup, il semble peu probable qu'il ya juste un arriéré de travail. IMO, l'option la plus probable est que quelque chose utilise des connexions et ne les libère pas rapidement. Êtes-vous sûr vous utilisez using dans tous les cas? Ou (par quelque mécanisme que ce soit) en libérant les connexions?

12
répondu Marc Gravell 2009-03-22 09:58:39

avez-vous vérifié les lecteurs de données qui ne sont pas fermés et la réponse.redirige avant de fermer la connexion ou un lecteur de données. Les connexions restent ouvertes lorsque vous ne les fermez pas avant une redirection.

11
répondu Ivo 2009-03-22 10:05:28

nous rencontrons ce problème de temps en temps sur notre site web aussi bien. Le coupable dans notre cas, c'est nos statistiques/index qui deviennent périmés. Cela provoque une requête précédemment en cours d'exécution rapide à (éventuellement) devenir lent et time out.

essayez de mettre à jour les statistiques et/ou de reconstruire les index sur les tables affectées par la requête et voir si cela aide.

9
répondu Alex Czarto 2009-06-14 22:51:42

vous pouvez spécifier la taille minimale et maximale du pool en spécifiant MinPoolSize=xyz et/ou MaxPoolSize=xyz dans la chaîne de connexion. Cette cause du problème pourrait être une autre chose, cependant.

5
répondu Mehrdad Afshari 2009-03-22 09:53:55

j'ai moi aussi rencontré ce problème lors de l'utilisation d'une couche de données de tiers dans une de mes applications .NET. Le problème était que la couche ne fermait pas les connexions correctement.

nous avons jeté la couche et nous en avons créé une nous-mêmes, qui se ferme toujours et dispose des connexions. Depuis lors, nous n'avons pas l'erreur de plus.

5
répondu Wim Haanstra 2009-03-22 10:50:46

si vous travaillez sur un code d'héritage complexe où une simple utilisation (..) {..} n'est pas possible - comme je l'ai été - vous pouvez consulter l'extrait de code que j'ai posté dans cette DONC, la question un moyen pour déterminer la pile des appels de la création de la connexion lorsqu'une connexion est potentiellement fuite (pas fermé après un délai d'attente). Cela rend assez facile de repérer la cause des fuites.

2
répondu LOAS 2017-05-23 12:10:33

ceci est principalement dû au fait que la connexion n'a pas été fermée dans l'application. Utilisez "MinPoolSize" et" MaxPoolSize " dans la chaîne de connexion.

2
répondu subramanian.m 2013-07-31 05:57:59

dans mon cas, je ne fermais pas L'objet 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
répondu DevelopZen 2015-08-24 15:31:37

N'instanciez pas la connexion sql trop souvent. Ouvrez une ou deux connexions et utilisez-les pour toutes les opérations sql suivantes.

semble que même lorsque Dispose dans les connexions l'exception est lancée.

2
répondu 2016-06-13 10:39:08

utilisez ceci:

finally
{
    connection.Close();
    connection.Dispose();
    SqlConnection.ClearPool();
}
2
répondu Jeno M 2017-10-18 10:50:18

Vous pouvez essayer aussi, pour résoudre les problème de délai d'attente:

si vous n'avez pas ajouté httpRuntime à votre webconfig, ajoutez cela dans <system.web> tag

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

et

modifiez votre chaîne de connexion comme ceci;

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

à la dernière utilisation

    try
    {...} 
    catch
    {...} 
    finaly
    {
     connection.close();
    }
2
répondu Ka_Ya 2018-01-02 14:37:14

ce problème que j'avais dans mon code. Je vais coller un exemple de code que j'ai survolé est venu en dessous de l'erreur. Le délai écoulé avant l'obtention d'une connexion à partir de la piscine. Cela peut s'être produit parce que toutes les connexions groupées étaient utilisées et que la taille maximale de la piscine était atteinte.

 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();**

Vous voulez fermer la connexion à chaque fois. Avant cela, je ne nous ai pas fait la connexion étroite en raison de cela, j'ai eu une erreur. Après l'ajout de l'instruction de fermeture i ont dépassé cette erreur

1
répondu Aravindhan R 2017-11-18 11:41:30

en plus des solutions publiées....

en traitant avec 1000 pages de code d'héritage, chacun appelant un Gers commun plusieurs fois, voici une autre façon de résoudre le problème:

dans une DLL commune existante, nous avons ajouté le CommandBehavior.CloseConnection option:

    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);   
    }

ensuite dans chaque page, aussi longtemps que vous fermez le lecteur de données, la connexion est également automatiquement fermé afin de connexion les fuites sont empêchés.

    IDataReader rs = CommonDLL.GetRS("select * from table");
    while (rs.Read())
    {
        // do something
    }
    rs.Close();   // this also closes the connection
1
répondu David Nelson 2018-05-31 05:32:46

vous avez divulgué des connexions sur votre code. Vous pouvez essayer d'utiliser l'utilisation pour certifier que vous les fermez.

 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
répondu EduLopez 2016-08-15 13:14:35

ce problème que j'ai rencontré auparavant. Il a fini par être un problème avec le pare-feu. J'ai juste ajouté une règle au pare-feu. J'ai dû ouvrir le port 1433 pour que le serveur SQL puisse se connecter au serveur.

0
répondu Feisal 2017-10-05 20:37:50