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

Bases de données Delphi Discussion :

Nombre maximal de curseurs ouverts atteint


Sujet :

Bases de données Delphi

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Points : 124
    Points
    124
    Par défaut Nombre maximal de curseurs ouverts atteint
    Bonjour,

    J'utilise une application serveur socket Delphi pour communiquer avec une application cliente windev mobile. Mon scan envoit des trames au serveur qui me retourne des réponses. Mon serveur de socket Delphi tourne en permanence.
    J'utilise Oracle et notamment le composant OracleSession pour me connecter à ma base de données.
    Après quelques mois j'ai eu une erreur "Nombre maximal de curseurs ouverts atteints".
    J'ai testé cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select * from V$system_parameter where name = 'open_cursors' ;
    Qui m'a permis de voir que j'avais une autorisation de 300 curseurs ouverts par session.
    J'utilise de nombreuses requêtes mais je prend soin de faire un .Close à la fin de chacune de mes procédures.
    J'ai ensuite regarder le nombre de curseurs actifs un instant T pour ma session grâce à cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select user_name, status, osuser, machine, a.sql_text
    from v$session b,
    v$open_cursor a
    where a.sid = b.sid
    and osuser =nomdemassesion/
    Et j'ai vu que j'avais 262 curseurs actifs... en stoppant mon serveur ce chiffre passe à 158...
    Je pense donc que des curseurs ne sont pas fermés... pourtant je prend soin de faire des .Close sur toutes mes requêtes utilisées à la fin de chacune de mes procédures....

    Est ce qu'il y'a quelque chose à faire sur le OracleSession ?
    Windows XP
    Delphi 7

    WinDev Mobile 17

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 453
    Points : 24 864
    Points
    24 864
    Par défaut
    utilise des try finally pour garantir qu'un Close correspond à un Open même si une exception se produit durant un traitement ou alors à cause d'un Exit trop bien caché !

    Si tu as le "sql_text" ça devrait t'aider à traquer les coupables ! non ?

    On ne peut que penser qu'il manque des Close, à cause de rupture dans le cheminement des fonctions !

    As-tu dans tes Objets OnAfterClose, OnAfterOpen ?
    Dans une phase d'analyse, enregistret dans un log toute ouverture et toute fermeture !
    Cela sera fastidieux à trouver tous les objets dans le code mais tu devrais au fur et à mesure trouver les fuites !

    Pour ma part, j'avais traqué aussi les Query non fermées dans un projet dont j'avais maintenance, les Query étant créés par une Factory (une chance), je pouvais aisément surveiller leur création, un thread scrutait régulièrement les adresses mémoires avec ma fonction RealAssigned (IsBadReadPtr couplé à ClassName, ClassType et is), je détectais ainsi les libérations et seules les Query non libérées trainaient
    En général, une Query était fermée puis libérée, pas de DataModule ni d'objets posés sur les fenêtres à quelques exceptions près !

    Comment gères-tu tes Query, tu as des DataModule et donc les Query sont créées une seule fois et tu fais des Open\Close !
    Ou tu utilises une Factory ou une instanciation manuelle locale à la fonction ?

    Pense que si tu peux utiliser Prepared sur tes Query les plus utilisées dont l'instance reste tout le long de ton serveur, leurs performances seront améliorées
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 533
    Points : 124
    Points
    124
    Par défaut
    J'utilise des try finally quasiment de partout...
    Pas de OnAfeterClose ni de OnAfterOpen...
    Je n'utilise pas de DatModule je créée simplement ma requête en début de procédure et j'utilise des .Execute, ou des .Exectue puis .Commit et je fais des .Close à chaque fin de procédure dans mon finally...

    Un exemple de procédure :

    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
    // -----------------------------
    // SI06 Test du numéro de série du colis
    //------------------------------
    procedure TestColisSerie(adIp : string; numeroCmd : string; ligne : string; lot : string; sMod : string; sAct : string; OraSession : TOracleSession; SerSocket : TServerSocket; idConnex : integer; Trace : TMemo);
    var
      oqSelect : TOracleQuery;
    begin
     
    oqSelect := TOracleQuery.Create(Nil);
    oqSelect.Session := OraSession;
     
      Try
        oqSelect.Close;
        oqSelect.SQL.Clear;
        oqSelect.SQL.Add('select count(*) as total from COLXRES where NUMXCOL=:num and LIGXCOL=:lig and LT1XCOL=:lot');
        oqSelect.DeclareAndSet('num', otInteger, StrToInt(numeroCmd));
        oqSelect.DeclareAndSet('lig', otInteger, StrToInt(ligne));
        oqSelect.DeclareAndSet('lot', otInteger, lot);
        if TestRequete(oqSelect, 'OPENREQ') then
        begin
          if oqSelect.Field('total') > 0 then
          begin
            envoiMsgSocket(idConnex, numeroCmd, 'NUMSERIEDEJA', SerSocket, Trace);
            maj_raoxres('', adIp, sMod, sAct, '', numeroCmd, '', '', '', 'Prep Chariot - Num Serie déjà saisi', '', 1, 0, 0, 0, 0, 0, 0, 0, 0, 'N', 'N', 'N', 'A', OraSession);
          end
          else
          begin
            envoiMsgSocket(idConnex, numeroCmd, 'SERIEOK', SerSocket, Trace);
            maj_raoxres('', adIp, sMod, sAct, '', numeroCmd, '', '', '', 'Prep Chariot - Num Serie Ok', '', 1, 0, 0, 0, 0, 0, 0, 0, 0, 'N', 'N', 'N', 'A', OraSession);
          end;
        end
        else
        begin
          envoiMsgSocket(idConnex, numeroCmd, 'ANOMALIERECHSERIE', SerSocket, Trace);
          maj_raoxres('', adIp, sMod, sAct, '', numeroCmd, '', '', '', 'Prep Chariot - Anomalie recherche num série', '', 1, 0, 0, 0, 0, 0, 0, 0, 0, 'N', 'N', 'N', 'A', OraSession);
        end;
      Finally
        oqSelect.Close; oqSelect.Free;
      End;
    end;
    Sachant que l'exécution de ma procédure se fait dans le TestRequete :

    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
    function TestRequete(requete : TOracleQuery ; lancer : string) : boolean;
    var
       x_i : integer;
       x_ok : boolean;
       erreurMsg : string;
    begin
      Result := True;
      try
        case AnsiIndexStr(lancer, ['OPENREQ', 'EXECUTE']) of
     
          0 : begin
                requete.Execute;
              end;
          1 : begin
                requete.Execute;
                requete.Session.Commit;
              end;
          -1 : begin
                 Result:=False;
                 LogErreur('Anomalie dans TestRequete  = '+lancer);// Message d''erreur : '+ e.Message);
               end;
        end;
        except on e:exception do
        begin
          Result:=False;
          LogErreur('Anomalie sur la requête ' + requete.SQL.Text +' : Message d''erreur : '+ e.Message);
        end;
      end;
    end;
    Windows XP
    Delphi 7

    WinDev Mobile 17

Discussions similaires

  1. ORA-01000: nombre maximum de curseurs ouverts dépassé
    Par opensource dans le forum Débuter
    Réponses: 3
    Dernier message: 20/04/2011, 13h30
  2. ORA-01000: Nombre maximum de curseurs ouverts atteint
    Par nihilist dans le forum Oracle
    Réponses: 2
    Dernier message: 18/08/2010, 12h08
  3. Nombre maximum de curseurs ouverts atteint
    Par vanhel dans le forum JDBC
    Réponses: 6
    Dernier message: 21/05/2008, 10h18
  4. Réponses: 6
    Dernier message: 17/09/2007, 12h50
  5. [Oracle] Nombre maximum de curseurs ouverts atteint
    Par lionheart33806 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 09/10/2006, 12h06

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