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

Delphi Discussion :

Accès concurrentiel à une Database FireBird


Sujet :

Delphi

  1. #1
    Invité de passage
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2026
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2026
    Messages : 11
    Par défaut Accès concurrentiel à une Database FireBird
    Bonjour,
    j'utilise Delphi XE10 avec les composants FireDac pour accéder à la Base de Données.
    j'aimerai savoir comment faire pour qu'une mise à jour sur une Table soit visible par tous les PC d'une même application.
    Exemple j'ajoute un Nouveau Client via un Formulaire Quand j'appuie sur le Bouton Confirmer je lance la requête Update.
    Si j'ai un autre PC qui veut consulter la fiche de ce client il trouve les nouvelles informations s'il fait un nouvel accès au même formulaire.
    J'espère avoir été clair.
    Quels sont les paramètres du composant FDTransaction Autocommit, AutoStart, AutoStop Etc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Fdtransaction1.StartTransaction;
    // Requete SQL
    FdQuery.Sql.Text := 'Insert into Tclient (c1,c2c,c3) values ("N1","CLIENT 1 ","ADR1")';
    Try
     FdQuery.ExecSql;
     FdTransaction1.Commit;
    Except on E:Exception do
       Begin
        Showmessage('Erreur Mise à jour '+E.Message); 
    End;
    End;

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 : 14 277
    Par défaut
    Dans le Except, ne pas oublier le RollBack

    Toutes les réponses sont dans Managing Transactions (FireDAC)

    Sinon, pour répondre, si Transaction explicite comme votre code via StartTransaction, c'est au moment du Commit, qu'un SELECT va retourner les données validées sur les autres connexions (locales ou distantes)
    il faut refaire le Close/Open ou le Refresh, cela ne se va pas se faire tout seul un dataset déjà ouvert
    Voir si FireBird permet des mécanismes TFDEventAlerter pour éventuellement faire un Refresh (même si ce n'est pas une bonne approche, cela sous-entend des ensemble de données ouverts trop longtemps, pire des TFDTable ).

    Et cela dépend du niveau d'Isolation et je ne parle même pas des transactions imbriquées.

    En AutoCommit à True, même pas besoin de faire StartTransaction/Commit, c'est fait d'un coup, pour la plupart des situations cela suffit
    Le StartTransaction est surtout utile si l'on insère un lot de donnée devant rester cohérent, un ensemble maitre-detail par exemple

    le Fdtransaction1 doit être lié à connexion de la FdQuery, quelque part ajouter, avant le StartTransaction par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FDQuery.Transaction := FDTransaction1;
    Autant reprendre l'exemple FireDAC.Comp.Client.TFDCustomTransaction.StartTransaction
    Cela utilise le RAD, c'est bien pour un tout petit projet pour un gros projet, le RAD deviendra ingérable, on va pas poser 300 TTable et 300 TDataSource dans un TDataModule (quoi que, je l'ai vu), le mieux c'est une Factory genre un GetQuery qui fourni un TFDQuery prêt à l'emploi et un GetQueryWithTransaction, couplé à une strucure with do try finally cela fait un code compact

    Si je reprend un vieux code du genre pour ADO de 2007
    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
    function TConnexionWrapper.GetQuery(const ASQL: string; APrepared: Boolean = False; AOwner: TComponent = nil): TFDQuery;
    var
      Query: TFDQuery;
    begin
      Result := nil;
     
      Query := TFDQuery.Create(nil);
      try
        Query.Connection := InternalConnexion; // TConnexionWrapper gère une ou plusieurs TFDConnection selon le schéma, les users plus ou moins propriétaire de certaines tables critiques, un user RGDP différent d'un user des données lambda par exemple
        Query.SQL.Text := ASQL;
        if APrepared then
          Query.Prepared := True;      .
        Result := Query;
        if Assigned(AOwner) then
          AOwner.InsertComponent(Result);
      finally
        if not Assigned(Result) then
          Query.Free();
      end;
    end;
     
    function TConnexionWrapper.GetQueryWithTransaction(const ASQL: string; APrepared: Boolean = False; AOwner: TComponent = nil): TFDQuery;
    var
      Query: TFDQuery;
    begin
      Result := nil;
      try
       Query := GetQuery(ASQL, False, nil);
       Query.Transaction := TFDTransaction.Create(Query); // Actuellement, l'affectation de l'objet transaction explicite est seulement supportée pour InterBase et Firebird.
       Query.Prepared := APrepared;    
       Result := Query; 
        if Assigned(AOwner) then
          AOwner.InsertComponent(Result);
      finally
        if not Assigned(Result) then
          Query.Free();
      end;
    end;
    Aide via F1 - Utilisez l'I.A. - 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é ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...

    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
    Invité de passage
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2026
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2026
    Messages : 11
    Par défaut
    Merci pour ces précisions.
    Donc si je comprends bien votre conseil mettre les paramètres AutoCommit et AutoStart à True et tout se ferait automatiquement. Sous réserve à chaque extraction de Données de refaire un Open.
    Etant entendu que pour une mise à jour par lot il faut délimiter les transactions par StartTransaction et Commit.
    je vais tester le tout.

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 : 14 277
    Par défaut
    Citation Envoyé par Med.Belarbi Voir le message
    Sous réserve à chaque extraction de Données de refaire un Open.
    Vous avez très bien compris, je parle de mon expérience Paradox, Interbase, MySQL, Sybase, Oracle, SQL Server avec respectivement BDE, IBX, MyDAC, DBExpres, ODAC, ADO ... pas de chance il manque FireDac et FireBird mais cela ne change pas grand chose.

    J'ai beaucoup pratiqué l'AutoCommit, avec des exceptions de Transaction Explicite (parfois via Procédure Stockée).
    La prise en compte est au Open SELECT après le Commit, si l'on a un projet orienté SQL, c'est souvent transparent.

    Par contre, surveillez la conciliation de données, imaginons user A ouvre la fiche du Client 1 et user B ouvre aussi la ficher du Client 1
    A modifie
    B modifie
    Les deux plus ou moins en même temps (en vrai c'est séquentiel, A écrit, B écrase)

    Important de ne générer l'UPDATE uniquement sur les champs modifiés, cela réduit l'écrasement.
    Si pas de chance, les champs modifiés sont les mêmes, ajouter une conciliation, ceux qui utilisent ADO connaissent bien le fameux "Une opération en plusieurs étapes a généré des erreurs" qui ne veut rien dire mais c'est que les données ont été modifié entre la lecture et l'écriture.

    Vous pouvez décider, le dernier qui écrit est celui qui a raison, la plupart du temps ça passe, au pire une journalisation des modifications des champs sensibles
    Mais prendre en compte le delta et émettre un conflit est une autre approche (l'utilisateur peut être dérouté, nous développeur, on peut le voir tous les jours avec des Commit non atomiques et des conflits sur les merge)

    Je ne l'ai vu complèment mis en place que dans un seul projet, avec même une gestion d'état (les user A et B qui consulte la fiche du Client 1, ont un indicateur qu'un autre utilisateur consulte la fiche, un second indicateur qu'un autre utilisateur modifie la fiche et enfin qu'une autre utilisateur a modifié la fiche, l'état change en temps réel, trigger, notification, event, un monstre à coder)

    La conciliation c'est dans le WHERE du UPDATE c'est d'inclure la PK évidemment et les valeurs d'origine
    Gérer le Affected Rows, si il n'est pas celui attendu, refaire un SELECT et produire un formulaire qui montre les valeurs à l'ouverture par user B, les valeurs à l'instant T modifié par user A et les données fusionnées (comme un Git Merge Conflit mais version champ)

    Il y avait même un expert (quelque part dans ADO) qui le faisait automatiquement mais très moche.
    Aide via F1 - Utilisez l'I.A. - 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é ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...

    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

  5. #5
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 931
    Billets dans le blog
    66
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Vous pouvez décider, le dernier qui écrit est celui qui a raison, la plupart du temps ça passe, au pire une journalisation des modifications des champs sensibles
    Mais prendre en compte le delta et émettre un conflit est une autre approche (l'utilisateur peut être dérouté, nous développeur, on peut le voir tous les jours avec des Commit non atomiques et des conflits sur les merge)

    Je ne l'ai vu complèment mis en place que dans un seul projet, avec même une gestion d'état (les user A et B qui consulte la fiche du Client 1, ont un indicateur qu'un autre utilisateur consulte la fiche, un second indicateur qu'un autre utilisateur modifie la fiche et enfin qu'une autre utilisateur a modifié la fiche, l'état change en temps réel, trigger, notification, event, un monstre à coder)
    Cela me rappelle le bon vieux temps où je travaillais sur IBM36 (en RPG), en ce temps là l'utilisateur était dirrigé par le programme désormais c'est l'inverse.
    Lorsque, j'ai voulu appliqué la même méthode pour des programmes windows (Delphi+INTERBASE) fin des années 90 je suis tombé sur des utilisateurs impatients fan du Alt+Ctrl+Suppr et du coup des enregistrements verrouillés par des utilisateurs non connectés ou reconnectés mais ayant oublié qu'ils étaient en train de verrouiller une fiche particulière. Ces incidents, fréquents, m'obligeaient à mettre en place des arrêts momentanés de la base de données pour "libérer" les enregistrements.
    Au final, la direction (souvent responsble de ces problèmes) a décidé d'abandonner cette tactique En pratique, depuis le début des années 2000, l'adage " le dernier qui écrit est celui qui a raison" n'a jamais posé trop de souci.

    Firebird (2.5 et + ) a changé les choses désormais avec les Triggers sur la Base de données (ONDISCONNECT) il est possible de gérer facilement ces incidents de blocage. Je n'ai pas eu le courage de les remettre (la direction ayant changé )

    Par contre, si vous voulez aller plus loin : à savoir indiquer à un utilisateur si quelque chose a changé dans la base de données voici quelques pistes.
    J'ai traduit un billet sur les évenements FireBird proposant d'utiliser un middleware pour répondre à la problématique. Toutefois, et cela fut ma conclusion, toutes les possibilités de Firebird n'avaient pas été prises en compte.

    Côté Delphi+Firedac, il existe FDEventAlerter qui permet de souscrire à la veille des évènements.

    reste que « Après une mise à jour en masse de tous les dossiers » FDEventAlerter risque de tout bloquer mais, là encore, une solution "interne Firebird" pourrait résoudre ce problème (Par exemple : trigger sur Transaction, variable de base de données globale etc..)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes), D13 (Florence)
    SGBD : Firebird 2.5, 3, 5 et SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

Discussions similaires

  1. [AC-2007] Accès a une BD firebird via ODBC très lent
    Par adlinformatik dans le forum Access
    Réponses: 0
    Dernier message: 27/02/2016, 17h01
  2. accès à une database firebird
    Par zerros dans le forum Débuter
    Réponses: 2
    Dernier message: 30/04/2010, 19h19
  3. Réponses: 2
    Dernier message: 07/05/2008, 23h57
  4. Refus d'accès à une base Firebird
    Par severine dans le forum Installation
    Réponses: 18
    Dernier message: 04/06/2003, 16h03

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