|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Membre du Club
![]() Inscription : avril 2004 Messages : 121 ![]() |
Bonjour,
Je cherche à me documenter sur la bonne façon d'utiliser les transactions dans une appli C++Builder avec les composants IBX. Jusque là, je n'ai pas trouvé réponse à mes questions : - l'utilisation d'un TIBTransaction est-elle obligatoire pour une simple insertion ou mise à jour d'enregistrement dans une table ? - Si on utilise un TIBTransaction, il semble que le commit doive être explicite (les transactions automatiques sont désactivées ?). Mais quand/comment faire ce commit lorsqu'on porte une appli BDE qui utilisait un TDBNavigator pour les insertions et mises à jour d'une table ? - Il semble que TIBTransaction effectue automatiquement un Start Transaction, mais pas le Commit... Comment bien gérer tout ça ? Je cherche donc un document, un post, un lien ou une explication non pas tellement sur les transactions, mais sur la bonne façon de les gérer dans le contexte Firebird/Composants IBX/C++Builder (voire Delphi...). Quelqu'un peut m'aider ou m'aiguiller SVP ?
__________________
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi ! Albert Einstein. |
|
|
00
|
|
|
#2 |
|
Membre éclairé
![]() Inscription : décembre 2004 Messages : 379 ![]() |
en principe, si tu ne gère pas les transactions, les composants ibx les gères via une transaction par défaut (à contrôler tout de même, car cela peux changer d'une version à l'autre!), mais de fait, ils ne font pas de comit automatique!
dans tous les cas, il est autement préféreable d'ouvrir une transaction, d'effectuer le traitement (attention, pas un million de update ou d'insert!) puis de lancer le commit en fin qui peux alors produire un rollback en cas de pépin. le malheur dans tous cela est que la programmation en c++ ou delphi et vachement lourde (je pratique depuis 5 ans...) et il est donc préférable de se construire ou de chercher sur le net des composants qui gère les transactions et commit automatiquement. j'ai cela, mais en delphi 5, seulement, donc je ne peux t'aider plus la dessus. si ton apply fait en boucle des inserts et des updates, fait un commit par exemple tous les 64 records à 10000 max, en dessous et au dessus cela ralenti la base, surtout au dessus. dans tous les cas, ne laisse pas de transaction ouverte trop longtemp, car c'est le meilleur moyen pour ce dire: "m'enfin, hier cela marchait et pas aujourd'hui"... surtout si tu ne backup/restaure pas souvent ta base et que le serveur se déconnecte de temps à autres (c'est pour cela qu'il y a le gardien...) donc en résumé: ouverture de la transaction, quelques requêtes, commit/rollback et rebelotte au prochain tour... |
|
|
00
|
|
|
#3 | ||
|
Membre du Club
![]() Inscription : avril 2004 Messages : 121 ![]() |
Salut,
Merci pour ta réponse, mais je n'ai pas dû assez insister sur le fait que j'attends surtout des explications sur le fonctionnement de TIBTransaction et comment bien gérer les transactions avec ce composant. En effet, le fait qu'il ouvre dès le départ une transaction et les méthodes dédoublées Commit/CommitRetaining et Rollback/RollbackRetaining me laissent un peu sceptique... Je ne vois pas très bien comment faire la démarche utlra classique : Code :
Ou alors, plus habitué aux transactions par pose de verrou, je ne sais pas adapter ma façon de travailler avec la méthode du versionning utilisée par Interbase/Firebird ? En insistant un peu auprès de mon ami Google, j'ai fini par trouver ces explications. Clair et intéressant, mais j'ai beau me torturer l'esprit, je ne vois pas bien comment adapter cela à mes applications telles que j'ai l'habitude de les concevoir... Ma question est donc : quelle est l'astuce qui m'échappe, ou qu'est-ce que je dois adapter dans ma conception d'applications ? Cette transaction ouverte en permanance et qu'on ne peut fermer sans fermer les tables, je n'en vois plus trop l'intérêt ???
__________________
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi ! Albert Einstein. |
||
|
|
00
|
|
|
#4 |
|
Expert Confirmé Sénior
![]() ![]() Pierre Ingénieur qualité méthodes Inscription : mars 2003 Messages : 3 726 ![]() |
Peut-être 1 complément d'info sur http://www.delphicenter.net/fr/ressources.asp
Maintenant, cette histoire de transaction permanente... ben Aucun intérêt, par exemple, pour des applis qui ne font que de la lecture...
__________________
"Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet) ----------------------- Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MPUsus magister est optimus |
|
|
00
|
|
|
#5 | |||
|
Membre Expert
![]() Frédéric Inscription : octobre 2002 Messages : 1 722 ![]() |
Citation:
Citation:
Et dire que c'est vachement lourd c'est un peu exagéré On peut avec les IBX avoir un comportement se rapprochant de l'auto commit de deux mannières : Soit dans les évènements AfterPost faire un commitRetaining. Soit utiliser un composant transaction par composant de mise a jour et mettre la propriété AutoStopAction de la transation à saCommit. Mais bon je pense qu'il est préférable (même si c'est vachement lourd Citation:
Par exemple si une appli1 ouvre une transaction snapshot. L'appli2 efface tous les enregsitrements (et commit). L'appli1 n'ayant pas encore fermée sa transaction snapshot peut voir tous les enregistrements supprimés par l'appli2. Typiquement une transaction snapshot permet d'avoir une photo de la base à un instant T, ce qui peut être très interressant pour certains traitements. Autre exemple le backup, d'une base utilise une tel transaction, ce qui a pour très gros avantage de pouvoir continuer à utiliser la base et à travailler dessus pendant le backup. La sauvegarde contiendra un ensemble de données cohérentes. Bien entendu la snaphot n'est pas celle la plus utilisée car l'isolement qu'elle assure va apporter quelques contraintes en utilisation courante. Je pense que celle la plus utilisée est la transaction ReadCommited. |
|||
|
|
00
|
|
|
#6 | |||||||
|
Membre du Club
![]() Inscription : avril 2004 Messages : 121 ![]() |
Bonjour,
Merci pour vos réponses et pardon pour mon retour tardif dû à un planning un peu chargé. Si je connaissais déjà la pluspart des tutos indiqués dans le lien de qi130, j'ai eu le plaisir d'en découvrir un sur les transactions qui m'a apporté quelques petites précisions sur le fonctionnement des transactions d'Interbase/firebird, entre autres l'utilité du CommitRetaining. Reste que j'ai toujours un peu de mal à voir comment m'y prendre avec ce TIBTransaction... Citation:
Code :
Donc, ma question reste : comment faire cela avec TIBTransaction ? Je vois à priori deux méthodes possibles, partant du principe que mon TIBTransaction a ouvert une transaction dès le lancement de l'appli : Code :
Code :
__________________
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi ! Albert Einstein. |
|||||||
|
|
00
|
|
|
#7 |
|
Membre Expert
![]() Frédéric Inscription : octobre 2002 Messages : 1 722 ![]() |
Le commit valide les modifications et ferme la transaction.
Le commitretaining valide les modifications mais ne ferme pas la transaction. D'un point de vue performance il est préférable pour le serveur de faire des commit car plus on maintient une tranaction longtems plus ca coute cher. Mais d'un point de vue pratique il est souvant plus facile de ne pas fermer la transaction. Donc il est préférable d'utiliser une transaction séparée pour les opérations de modifications et non celle ouverte par défaut par le TIBDatabase. |
|
|
00
|
|
|
#8 | ||
|
Membre du Club
![]() Inscription : avril 2004 Messages : 121 ![]() |
Re...
Merci pour cette précision, Barbibulle. Et pardon pour ces questions dignes d'un newbie... J'aurais peut-être aussi dû faire quelques essais avant de poster, mais bon : j'ai un peu tendance à croire d'emblée ce qui est écrit dans les tutos... Citation:
Citation:
Et on n'a pas de problèmes de fermetures-réouvertures ?Bon, si aucun tuto n'explique tout ça, il faudra que j'en fasse un quand j'aurai tout bien compris (si j'y arrive un jour
__________________
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi ! Albert Einstein. |
||
|
|
00
|
|
|
#9 |
|
Membre Expert
![]() Frédéric Inscription : octobre 2002 Messages : 1 722 ![]() |
Hummm beaucoup de questions et de confusions.
Et en effet ce n'est pas facile à aborder car il y a pas mal de paramètres à prendre en compte. Personnellement quand j'ai débuté sur le sujet je me suis fait une appli de test. Avec une transaction dont je pouvais changer les caractèristiques. Un composant TIBDataSet pour interroger une table et modifier ses données. Je lancai cette application deux fois (pour simuler deux clients (plus précisément deux transactions) et j'ai fais mes expériences pour comprendre, ce qu'on pouvait faire et ce qu'il ne falait pas faire. Sinon pour info : 1/ Le TIBTransaction qui est attaché à votre TIBDatabase est celui qui est utilisé par défaut par toutes vos TIBDasaSet et autres. Donc en absence de précision de votre part tous les composants d'accès à vos données et de MAJ vont utiliser cette transaction (un TIBTransaction = Une et une seule transaction). Pour une petite application qui n'a qu'un écran celà peut suffire. Mais le plus souvant on a besoin de plusieurs transactions. 2/ Lorsqu'on attache un TIBDataSet (ou autres TIBQuery) on précise sur quel TIBDataBase on va travailler (Propriété DataBase) et lors de ce rattachement Delphi automatiquement attribue la transaction de la database à la propriété Transaction. Donc par défaut votre TIBDatabase utilise le TIBTransaction de votre TIBDataBase. Mais rien ne vous empèche d'en utiliser un autre. Poser un autre TIBTransaction sur votre fiche et utiliser le pour ce TIBDataSet. Ainsi ce TIBDatsSet a sa propre transaction que vous pouvez d'ailleur configurer différemment (Snapshot ou readcommited ou ...) que le TIBTransaction proposé par défaut par le TIBDatabase. Ainsi pour commiter vos MAJ il vous suffit de faire IBDataSet.Transaction.Commit; (et celà fermera votre TIBDataSet et tous les autres DataSet que vous aurez éventuellement attaché à cette nouvelle transaction) ou un IBDataSet.Transaction.CommitRetaining; si vous voulez garder ouvert votre dataset. Dans une application offrant la possibilité d'ouvrir plusieurs fenetres simultanément il est illusoire de ne pas utiliser plusieurs transactions même si c'est une application monoposte (et donc un seul utilisateur en avec le serveur en local). En effet si vous n'aviez qu'une transaction (celle du TIBDataBase par exemple) et que vous ouvriez deux fenetres de votre appli. Dans la fenetre 1 : Fen1 vous faites des mises à jours de données dans la fenetres 2 : Fen2 vous faites d'autres modifications. Si dans Fen2 vous faites un commit, vous allez valider les modifications faites dans la transaction (la même que Fen1) et donc vous allez valider les modif faites dans Fen1. De même que si Fen1 /Fen2 fait un RollBack celà annule ce qui a été fait dans l'autre fenetre, ce qui n'est pas le comportement qu'on attend en générale... On voit bien dans ce cas et à plus forte raison sur en milieu conccurentiel il faut plusieurs transactions. Une transaction pour Fen1 et une pour Fen2. Après il faut se pencher sur la la visibilité de la transaction. Ce que vous lui permettez de lire provenant des autres transaction(comme MAJ). Imaginons que vous ayez besoin de faire une edition d'une table suivi de statistiques (comptage du nombre d'enregistrement etc...). Vous me direz que souvant ce type de stat est fait en local par le logiciel d'edition. Mais admetons que l'on veuille le faire en SQL. Vous allez définir une transaction T1 A/sur lequel vous allez attaché un TIBQuery contenant le select nom, prenom, ... from matable order by nom, prenom à partir du résultat vous lancez l'édition. B/Vous ouvrez un second TIBQuerycontenant le select count(*) from Matable. Et obtiendrez peut etre le nombre de personnes figurant sur l'édition. Si vous avez T1 en readCommited vous avez un risque qu'une autre personne efface de votre table un enregistrement déjà imprimé et commit avant que votre programme ne fasse le B/. Dans ce cas le count(*) comptera le nombre de personne dans la table et non le nombre de personne que vous avez imprimé. Par contre si vous aviez configuré T1 en snapshot (et que vos deux TIBQuery utilisent cette transaction) vous optiendrez le bon résultat. Le count(*) ne tiendra pas compte des modifications apporté par les autes transactions depuis son ouverture. Bon il y a beaucoup de choses à dire mais j'espère avoir éclaissi vos lumières sur le sujets et sur les possibilitées des transactions. Il vous reste à tester par vous même, notamment un sujet que je n'ai pas abordé : La modification d'un même enregistrement par deuux transactions différentes... Tout un programme. |
|
|
00
|
|
|
#10 |
|
Membre du Club
![]() Inscription : avril 2004 Messages : 121 ![]() |
Bonjour,
Merci pour votre réponse détaillée, Barbibulle. Cela confirme l'impression que je commençais à me faire : dans l'absolu, il faudrait presque un TIBTransaction chaque fois qu'on veut une transaction... Bon, en pratique, on doit pouvoir en récupérer beaucoup après un premier usage et s'en resservir. Mais je trouve ça finalement assez lourd effectivement (peut-être est-ce ce que voulait dire jean-jacques varvenne)... Je trouve beaucoup plus simple et clair quand c'est le composant base de données (l'équivallent de TIBDatabase) qui crée automatiquement une nouvelle transaction par une méthode StartTransaction, et que par contre la transaction ainsi créée n'a aucun comportement automatique. Mais bon, les choses étant ce qu'elles sont, il faudra bien faire avec... Ou trouver d'autres composants, mais pour l'appli que j'ai en cours, je me contenterai des IBX... C'est vrai qu'un des avantages (heureusement qu'il y en a quand même N'empêche que j'en suis encore à me demander si ce n'est que le fait de changer mes habitudes qui me gène... Les quelques avantages des IBX ne me paraissent pas compenser leurs inconvénients... Bon, puisqu'il semble qu'il n'y ait pas de tuto plus détaillé que ce que j'ai déjà trouvé, il ne me reste effectivement qu'à faire une appli test... J'ai l'impression de retourner 20 ans en arrière quand j'avais fait cela pour bien comprendre le mécanisme des transactions (sur des ensembles de fichiers indexés, les SGBD n'étaient encore que très peu connus et répandus à l'époque) !
__________________
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi ! Albert Einstein. |
|
|
00
|
|
|
#11 |
|
Membre éclairé
![]() Inscription : décembre 2004 Messages : 379 ![]() |
quand je disais que c'est vachement lourd... 8) un ibquery + un ibtransaction, et ne jamais oublier les commits! sinon gare au comportement hératique de l'appli et de la base de données avec des questions du genre, "m'enfin, pourtant je l'ai fait..." sans compter que de nombreuses transactions entamées et non fermées ralentissent la base de données, puisque le moteur de la base doit lire toutes les transactions ouvertes pour déterminer quelle version donner. il y a d'ailleurs des outils qui permettent de contrôler ce problème de transactions (avec ib7 entre autre) la dessus, bon amusement (si,si) et surtout ne jamais oublier "que la transaction soit avec toi..."
|
|
|
00
|
|
|
#12 | |||
|
Membre Expert
![]() Frédéric Inscription : octobre 2002 Messages : 1 722 ![]() |
Citation:
Citation:
Mais ca aurait pu être un integer unique renvoyé par un startTransaction c'est vrai, mais dans ce cas là il faut se le mémoriser et donc se trimballer la déclaration d'un integer dans le code. Puis lorsqu'on voudrait ouvrir un Query en utilisant cette transaction il faudrait avant l'open préciser l'identifiant de cette transaction... Bref je ne trouve pas ça mieux. Citation:
Donc en gros les IBX vous apportent une possibilité de faire mieux mais au prix c'est vrai d'un petit changement de comportement de programmation. Maintenant il n'y a aucunne obligation d'utiliser ses possibilitées. |
|||
|
|
00
|
|
|
#13 | |
|
Membre du Club
![]() Inscription : avril 2004 Messages : 121 ![]() |
Bonjour,
Ok, je commence à comprendre ! En fait, le gros avantage du TIBTransaction, c'est que ça permet d'avoir des transactions simultanées. Etant de la vieille école, et ayant toujours travaillé avec des verrous, j'ai pour ma part appris à travailler en ne faisant jamais de transactions simultanées au sein de la même application. Et du coup, j'étais resté un peu dans cette idée, doù effectivement un certain nombre de malentendus et d'incompréhensions. En plus, pour moi, une transaction a une durée de vie très courte, qui commence au StartTransaction et finit au Commit ou Rollback. Dans un environnement à verrous, cela est presque indispensable d'avoir de telles restrictions. De plus, cela oblige à bien réfléchir aux transactions qu'on ouvre, et permet d'éviter pas mal de dead locks. Donc, j'ai bien à revoir en profondeur ma façon de concevoir les choses pour comprendre le fonctionnement des IBX avec leur transaction qui démarre et s'arrête avec l'application (oui : j'exagère, mais c'est comme ça que je le ressentais !)... Maintenant, est-ce vraiment intéressant d'avoir plusieurs transactions simultanées ? J'ai tant été habitué à ce que ce ne soit pas possible que je n'en vois pas l'intérêt. Ca me fait l'impression d'être comme beaucoup de choses : on découvre une nouvelle possibilité, et on s'aperçoit que c'est bien utile dans certains cas. Du coup, on en profite, peu à peu on en abuse, et pour finir on ne peut plus s'en passer, au point qu'on ne parvient plus à concevoir qu'il était possible auparavant de faire sans... Ceci n'est bien évidemment pas une critique : je m'interroge simplement sur le bien-fondé d'avoir plusieurs transactions ouvertes simultanément en permanence. Certes, cela peut être très utile dans certains cas, et il serait dommage de ne pas en profiter. Mais je pense qu'il faut rester vigilant pour ne pas en abuser. Mais est-ce possible ? Le fait même d'avoir cette possibilité implique une mise en oeuvre lourde et différente qu'on ne peut plus utiliser de la même façon... Finalement, je regrette que les deux possibilités ne soient pas offertes : travail en transactions uniques ou multiples. Il serait alors possible d'utiliser les transactions multiples là où elles sont réellement utilles et les transactions uniques dans la majorité des cas où elles suffisent largement... Citation:
Ne le prenez pas mal : je me fais l'avocat du diable et prêche le faux pour savoir le vrai
__________________
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi ! Albert Einstein. |
|
|
|
00
|
|
|
#14 |
|
Membre Expert
![]() Frédéric Inscription : octobre 2002 Messages : 1 722 ![]() |
Vous ne pourez de toute façon pas fonctionner comme avant.
IB et FB utilisent la technique du versionning alors que vous avez l'habitude de la technique du locking. La première différence, celà va être que vous pourrez avoir une transaction snapshot (ce qui était impossible avec le locking à moins de locker toutes les tables faisant partie du traitement et donc de pennaliser les autres le temps de ce traitement). Mais celà implique que pour une simple lecture vous soyez obligé de démarrer une transaction. Et ca c'est je dirai le plus gros changement d'habitude. Comme je vous l'ai déjà dit plus haut, pour les petites applications vous pouvez vous contanter de la transaction par défaut que vous mettrez en mode readCommited. Et vous faites dans votre application des commitRetainning. C'est ce qui se rapproche le plus je pense de votre ancien mode de fonctionnement. |
|
|
00
|
|
|
#15 |
|
Membre du Club
![]() Inscription : avril 2004 Messages : 121 ![]() |
Bonjour,
Merci de vos réponses. Effectivement, ça fait pas mal de changement dans les habitudes. Je ne suis pas encore convaincu que c'est mieux, mais bon, je suis certainement encore trop conditionné par ce que j'ai toujours fait pour juger
__________________
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi ! Albert Einstein. |
|
|
00
|
|
|
#16 | |
|
Membre Expert
![]() Frédéric Inscription : octobre 2002 Messages : 1 722 ![]() |
Citation:
Donc pour conclure, ce n'est pas le systeme absolue de même que le locking ne l'est pas (sinon tout le monde utiliserait le systeme en question...) Par contre avec le versionning, j'ai oublié de le dire : fini les problemes de maintenance, où les enregistrements restent lockées (suite à un plantage ou reboot sauvage d'un poste). Personnellement je suis très contant du versionning même si j'ai du remettre en question pas mal de mes méthodes de travail. |
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com