IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Accès aux données Discussion :

Npgsql: Timeout while getting a connection


Sujet :

Accès aux données

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 19
    Points : 13
    Points
    13
    Par défaut Npgsql: Timeout while getting a connection
    Bonjour,

    Je souhaite changer la méthode d’accès a notre bdd Postgres, en mettant en place une couche d'accès aux donnée fonctionnant avec la fabrique de classe proposée par Npgsql.

    J'ai modifier le machine.config afin d'y ajouter le nouveau provider.
    J'ai ensuite créer une classe abstraite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    public abstract class DbSource : IDisposable
        {
     
            protected DbConnection Connection;
     
            protected DbProviderFactory Factory;
     
            public DbSource()
            {
                String ConnectionString = ConfigurationManager.AppSettings["UseConnectionString"];
                Factory = DbProviderFactories.GetFactory(ConfigurationManager.ConnectionStrings[ConnectionString].ProviderName);
                Connection = Factory.CreateConnection();
                Connection.ConnectionString = ConfigurationManager.ConnectionStrings[ConnectionString].ConnectionString;
                Connection.Open();
            }
     
            public void Dispose()
            {
                Connection.Close();
                Connection.Dispose();
            }
        }
    Puis j'ai réaliser une classe d'implémentation avec les méthodes d’accès et de manipulation des données.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class DDefault : DbSource
    {
     
            public DDefault(): base() { }
     
            ... Méthode d'accès
    }
    Lors des tests de charge une exception est levée: Exception non gérée*: System.Exception: Timeout while getting a connection from pool. Comme si il n'y avait plus suffisamment de connexion disponible dans le pool (Min=10, Max=50). Ce qui me fait penser que le destructeur de la classe de base n'est pas appelé. Dois-je mettre le code suivant dans toute mes classe d'implémentation, ou y a t'il quelques chose d'autre a faire ???
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public new void Dispose()
            {
                base.Dispose();
            }

    Merci

  2. #2
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Non, ca ne va rien résoudre le fait de mettre tes disposes partout.
    Le problème probable est que ton code ne respecte pas un best-practice simplement,

    Citation Envoyé par Laurent WOLO
    Toujours ouvrir une ressource couteuse tardivement et la libérer très tôt.
    Est ce que tu peux nous faire voir le code de tes tests de charge ?

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 19
    Points : 13
    Points
    13
    Par défaut
    Bonjour,

    J'ai trouvé une parade qui me permet d'éviter cette exception...
    Le thread qui accèdent à la base de donnée sont placés dans le ThreadPool de l'application, j'ai donc limité la taille de ce pool qui par défaut était à 100 (4 cores * 25).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ThreadPool.SetMaxThreads(3, 3);
    Si quelqu'un a un exemple sur la manière de générer ce genre d'exception, je suis toujours preneur

  4. #4
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Non, tu modifies tes conditions de tests pour te satisfaire !

    Non essaie de tester ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //Toute ta gymnastique ici
    Using (DDefault db= new DDefault())
    {
         //Execute une requête SQL ici rien d'autre ici
    }
    Tu devrais améliorer tes performances.

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 19
    Points : 13
    Points
    13
    Par défaut
    Bonjour,

    effectivement cela na rien résolu, c'est pour ça que j'ai mis en place la solution postée juste après toi. Depuis cette limitation l'application se comporte beaucoup mieux.

    Dans notre cas il s'agit principalement de stress test, car il s'agit d'une application gérant des centaines de connexions presque simultanées (à quelque dizaine de seconde près) plusieurs fois par jour.

    Script du test (en php):
    Le script parcours deux répertoires contenant les données fraîches. Il récupère un identifiant sur les fichiers puis envoie au serveur, via le réseau, un signal respectant 1 protocole établi dans la fonction writesignal().

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    <?php
    	include_once('./lib/library.php');
    	error_reporting(E_ERROR | E_PARSE);
    	$filename = getcwd() . '\files\actions.txt';
     
    	$mdbDirectory = '../triggers_data/data/mdb';
    	$cntDirectory = '../triggers_data/data/cnt';
     
    	$DataFileArr = array();
     
    	if($dossier = opendir($mdbDirectory))
    	{
    		while(false !== ($fichier = readdir($dossier)))
    		{
    			$elem = split("_",$fichier);
    			if($elem[0] != "." && $elem[0] != ".." && !in_array($elem[0], $DataFileArr ))
    			{
    				array_push($DataFileArr, $elem[0]);
    			}
    		}
    	}
    	if($dossier = opendir($cntDirectory))
    	{
    		while(false !== ($fichier = readdir($dossier)))
    		{
    			$elem = split("_", $fichier);
    			if($elem[0] != "." && $elem[0] != ".." && !in_array($elem[0], $DataFileArr ))
    			{
    				array_push($DataFileArr, $elem[0]);
    			}
    		}
    	}
     
    	$timerstart = microtime(true);
    	$confirm = new Confirmation();
    	$confirm->Action = "SIG";
    	$confirm->RetCode = '0';
    	foreach ($DataFileArr as &$value) {
    		$confirm->SiteNo = $value;
    		$rc = controlConfirm($confirm);
    		if($rc == '00'){
    			//envoie du signal au serveur applicatif
    			if (!writesignal($confirm->ToCsv(), $filename)){
    				$rc = '-1';
    			}
    		}
    		echo 'SIG FROM ' . $confirm->SiteNo . '    STATUS:' . $rc . '<br>';
    	}
            $timerend = microtime(true);
    	$script_time = number_format($timerend - $timerstart, 3);
    	echo 'Script exécuté en ' . $script_time . ' seconde(s)';
    ?>
    Non, tu modifies tes conditions de tests pour te satisfairte !
    Non, mon script de test ci dessus n'a pas changé. C'est la manière dont je gère mes tâches au sein même de l'application qui a changé. Cependant tu as raison, il faut que je change l'ordonnancement des mes actions sur la classe DDefault (ainsi que les autre) afin de libérer la connexion plus vite.

    A bientot

  6. #6
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Est ce que tu as essayé de voir le comportement des compteurs de performances pour obtenir le nombre de requêtes/connexions simultannées ?

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

Discussions similaires

  1. La valeur Timeout de la fonction connect()
    Par midou256 dans le forum C
    Réponses: 0
    Dernier message: 15/02/2012, 14h07
  2. Réponses: 1
    Dernier message: 18/05/2010, 13h23
  3. Error Occurred While getting Resultset
    Par aminox1 dans le forum Autres outils décisionnels
    Réponses: 0
    Dernier message: 23/07/2009, 15h51
  4. Cannot get a connection, pool exhausted
    Par questionneuse dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 09/08/2007, 07h31
  5. Réponses: 3
    Dernier message: 11/08/2006, 15h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo