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 :

Problème avec Delphi Firedac SQLite et les commit


Sujet :

Bases de données Delphi

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Mai 2002
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Problème avec Delphi Firedac SQLite et les commit
    Bonjour tout le monde,

    J'ai une application Delphi (10.2.3) qui utilise Firedac et SqlLite.
    L'application fonctionne très bien mais j'ai remarqué une chose étrange. lorsque j’insère un très grand nombre d'enregistrement (> 60000), la mémoire de l'application ne cesse d'augmenter, même en faisant régulièrement des commit. Je remarque aussi que physiquement ma base de donnée ne change pas pendant le process (elle garde la même taille et la même date de modification).
    La fermeture de l'application (ou la base de donnée) va prendre quelques minutes (avec le pointeur SQL) et seulement à ce moment là, le fichier physique de ma base de données sera modifié.

    Voici un exemple de test
    Ma base de donnée est très simple
    CREATE TABLE t_stritems ( IdItels INTEGER, St01 VARCHAR (200), St02 VARCHAR (200), St03 VARCHAR (200), PRIMARY KEY(IdItels) )

    J'utilise un TFDconnection ainsi qu'un TFDQuery avec les paramètres par défaut. CachedUpdate est à false

    Lors de la première modification un fichier .db-journal est créé dans le répertoire de la base de donnée. Ce fichier journal est supprimé automatiquement par firedac à la clôture de la base

    Connect the database :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      FDConnection1.Connected := false;
      FDConnection1.Params.Clear;
      FDConnection1.Params.Add('DriverID=SQLite');
      FDConnection1.Params.ADD('Database=' + Edit1.text);
      FDConnection1.Connected := true;

    Insertion des enregistrements

    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
    FDQuery1.Connection := FDConnection1;
    FDQuery1.close;
    fdquery1.sql.clear;
    fdquery1.sql.add('DELETE FROM t_stritems');
     
    FDConnection1.StartTransaction;
    fdquery1.ExecSQL;
    FDConnection1.Commit;
     
    fdquery1.sql.clear;
    fdquery1.sql.add('SELECT * FROM t_stritems');
    fdquery1.Open;
     
     
    for i := 0 to 15 do
      begin
        for j:= 1 to 2000 do
          begin
            FDQuery1.append;
            FDQuery1.FieldByname('IdItels').asInteger := (i*2000) + j;
            FDQuery1.FieldByname('St01').asString := 'Text 01 Number : ' + FDQuery1.FieldByname('IdItels').asString;
            FDQuery1.FieldByname('St02').asString := 'Text 02 Number : ' + FDQuery1.FieldByname('IdItels').asString;
            FDQuery1.FieldByname('St03').asString := 'Text 03 Number : ' + FDQuery1.FieldByname('IdItels').asString;
            FDQuery1.post;
          end;
        FDConnection1.Commit;
      end;
    end;

    Comment faire pour que le Commit soit pris en compte ? j'ai l'impression que les données sont vraiment insérer qu'à la fermeture de la base.

    si vous avez des idées, je suis preneur

    d'avance merci

    Romuald

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Il me semble que le problème vient de la connexion (ce que suggère le journal)
    on peut avoir les infos sur la connexion ? (en bref une image de l'éditeur de connexion Firedac devrait faire l'affaire)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Dans ton code, il y a deux Commit pour un seul StartTransaction, cela ne va pas, tu devrais encadrer chacun ainsi
    Un second StartTransaction devrait être dans la boucle (dans le for 0..15 ça fera 16 appels de Start + 16 appels de commit)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    FDConnection1.StartTransaction();
    try
      ... SQL
     
      FDConnection1.Commit();
    except
      on E: Exception do
      begin
        FDConnection1.RollBack();
        raise;
      end;
    end;
    Pour ce type d'insertion, je préfère de loin faire des INSERT préparé et paramétré que d'utiliser Append/Post
    En plus tout ce que je viens de dire la bonne structure de code et le INSERT, c'est juste dans la documentation : Transactions, verrouillage, threads et curseurs SQLite


    Pour la mémoire, tant que la Query subissant des Append est ouverte, cela consomme et avec la gestion des blocs, la libération n'indiquera pas forcément une diminution de l'allocation de l'application mais plus une réserve que l'application garde pour de prochaines allocations

    Je ne connais pas SQLite, j'espère que ce n'est pas comme avec le BDE/Paradox et FlushBuffers
    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

  4. #4
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 496
    Points : 2 762
    Points
    2 762
    Billets dans le blog
    10
    Par défaut
    Je l'ai fait d'une autre manière. Je reste à mémoire constante et le tout en 13 secondes

    Nom : Capture.PNG
Affichages : 619
Taille : 3,5 Ko

    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
     
    procedure TForm1.FormActivate(Sender: TObject);
    var
      i, j: integer;
    begin
      FDQuery1.sql.clear;
      FDQuery1.sql.add('DELETE FROM t_stritems');
      FDQuery1.ExecSQL;
      FDTable1.Open;
         for i := 0 to 15 do
      begin
        for j := 1 to 2000 do
        begin
          FDTable1.Append;
          FDTable1IdItels.value := (i * 2000) + j;
          FDTable1St01.value := 'Text 01 Number : ' + FDTable1IdItels.AsString;
          FDTable1St01.value := 'Text 02 Number : ' + FDTable1IdItels.AsString;
          FDTable1St01.value := 'Text 03 Number : ' + FDTable1IdItels.AsString;
          FDTable1.post;
        end;
      end;
      FDTable1.Close;
      Application.Terminate ;
    end;

Discussions similaires

  1. Problème avec Delphi (rtl90.bpl)
    Par fouad93290 dans le forum Delphi
    Réponses: 5
    Dernier message: 09/01/2007, 11h43
  2. vclskin avec delphi 5/6, comment les installer?
    Par avogadro dans le forum EDI
    Réponses: 1
    Dernier message: 09/05/2006, 19h46
  3. [GD] Problème avec la librairie GD et les header !!
    Par jesspepette dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 15/10/2005, 12h09
  4. [JMeter] Problème avec la boucle infinie pour les tests
    Par zegreg dans le forum Tests et Performance
    Réponses: 1
    Dernier message: 05/10/2005, 11h41
  5. Réponses: 5
    Dernier message: 24/04/2005, 04h09

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