![]() |
Datenbank: Interbase • Version: 7.1 • Zugriff über: Über die IB-Komponenten
IB-Transaktionen
Hallo an alle,
seit kurzem versuche ich mit diesen Komponenten zu arbeiten. Bisher habe ich ausschließlich über die BDE gearbeitet. Aber was Transaktionen sind und wie man sie benutzt ist mir äusserst suspekt. Kann mir jemand helfen das zu verstehen? Braucht man pro Database nur eine oder mehrere?? Danke im Voraus Jochen |
Re: IB-Transaktionen
Moin,
über die Transaction der Interbase wickelst du alles ab, was von oder zur Interbase geschickt wird. Sie bildet also die Verbindung zwischen einer Kompo (IBStoredProc, IBDataSet usw.) und der Interbase. Zitat:
Bevor du Daten an die IB schickst must Du also ersteinmal die Transaction öffen und wenn das fertig ist, die Transaction wieder schließen.
Code:
//zum lesen
If Not IBTrans.InTransaction Then IBTrans.startTransaction //startet die Transaktion Try With Query1 Do Begin open; //Wenn es mit Parameter erfolgt, dann schiebe ich das immer in ne extra Procedure Edit1.Text:= Field[0].AsString; ... ... end; except; IBTrans.Rollback //verwirft das Ergebnismenge end; IBTrans.Commit; //schließt die Transaction end; Zitat:
|
Re: IB-Transaktionen
Gugg mal
![]() Ich denke, man benötigt pro Database nur eine Transaktion. @Albi: Bringt das Vorteile mit 2 Transaktionen? |
Re: IB-Transaktionen
Zitat:
Ein kleines Bsp.: Du hast ein Prog mit mehreren Forms, die Du alle gleichzeitig bearbeiten kannst. Du machst nun das eine Form auf - startest die Transaction - und bearbeitest die Daten und sagst speichern (Transaction bleibt offen) nun noch ein weiteres Form bearbeitest auch hier die Daten und willst speichern. Nun kommt ein Fehler und es erfolgt ein Rollback, somit sind die Daten aus dem anderen Form auch nicht gespeichert. Oder Du 2 User wollen den gleichen Datensatz bearbeiten/anschauen. Du nimmst nur eine Transaction und setzt die Trans auf Lesen-schreiben Tabellenstabilität und schon kann nur einer den DS lesen, da ja ein Lock auf diesem liegt. Oder anderherum, 2 User bearbeiten den DS ohne das eine Sperre oder sonstwas gelegt wurde, dann hat der als letztes auf speichern klickt gewonnen. Besonders mergen wird man das, wenn man dann noch mit DBEdit arbeitet. Also ich habe mir angewöhnt, fürs speichern und lesen zwei Transaction zu nehmen. Aber das muss im enteffekt jeder für sich selbst entscheiden, wie er mag. |
Re: IB-Transaktionen
In meiner Anwendung starte ich die Transaktion beim Programmstart und wenn ich einen Datensatz geändert habe führe ich ein CommitRetain aus.
Wenn ich dich richtig verstanden habe, bringt es aber nicht viel wenn du fürs Lesen und Schreiben eine getrennte Transaktion hast. Du bräuchtest doch nur für jedes Fenster eine eigene Transaktion, oder? Nur mal an einem Beispiel erläutert ... In einer Bank werden Überweisungen gebucht und an dem PC werden 2 Fenster zum Überweisungen buchen geöffnet. Dann sollte jedes Fenster seine eigene Transaktion besitzen, weil die beiden überweisungen nichts miteinender zu tun haben aber in jedem Fenster hat die Abbuchung vom einen Konto und die Aufbuchung auf das andere Konto was mit einander zu tun und dabei darf nix schief gehen. Also gehört das in eine Transaktion. Das gewährleistet auch wenn die eine Buchung fehl schlägt ist die 2. Buchung nicht davon betroffen. -Transaktion öffnen (Auf die richtige transparenz achten) -Alles was in zusammenhang mit der einen Überweisung ist tun (lesen des Datensatzes, abbuchen vom einen Konto, aufbuchen auf das andere Konto ...) -Wenn alles ok -> Commit oder wenn ein Fehler aufgetreten ist Rollback Das mit den 2 User verhinderst du doch sonst auch nicht. Da hilft doch nur eine andere tranzparenz zu wählen. Und die muss natürlich jeder selbst entscheiden welche am besten geeignet ist für ihn. |
Re: IB-Transaktionen
Das ist ja alles richtig. Ich habe mich da wohl etwas ungünstig ausgedrückt. Generell sieht es bei mir so aus, das ich für jedes Fenster ein eigene Transaktion habe. Mein Beispiel war hierauf bezogen
Zitat:
Also öffne ich Read-Trans nur zum Lesen und sobald die Daten da sind, wird diese auch gleich wieder geschlossen. Und die zum speichern wird nur in der Zeit geöffnet, wo die Daten zum Server gesendet werden. Da man ja die Trans-Zeiten so gering wie möglich halten soll. Zitat:
Im enteffekt ist das Ergebnis das gleiche, nur das ich mich so nicht um die jeweiligen Einstellungen kümmern muss (sicher weil es so bequemer ist :-D). |
Re: IB-Transaktionen
Ihr betrachtet eine Transaktion IMHO zu sehr als eine Muliuser/Multitasking-Angelegenheit. Die machen aber auch in einer Einzelplatz Anwendung einen Sinn.
Es geht darum, entweder eine Reihe von Änderungen an der Datenbank alle durchzuführen oder keine. Beispiel Rechnung : Ich gebe Kunden-Nr. ein und dann ein paar Artikel und die Mengen. Was muß nun beim Speichern gemacht werden ? Die Mengen müssen vom Laberbestand abgebucht werde, es müssen für die Rechnungspositionen neue Datensätze angelegt werden, die Kunden und Artikelstatistik muß aktualisiert werden usw. Dies könnte man z.B. alles machen, nach jeder Mengeneingabe. Wenn ich jetzt schlau bin, dann habe ich die Transaktion gestartet, schon bevor ich den ersten Artikel eingebe. Warum ? Ich habe mich nämlich vertan :mrgreen: und für den falschen Kunden bereits 100 Rechn.-Positionen eingegeben, also sind zwar die 100 Lagerbestände richtig geändert, aber die Kundenstatistik usw. stimmt auf keinen Fall mehr. Ein DAU würde nun das alles noch einmal mit - eingeben (wenn das Programm das überhaupt zuläßt) und hoffen, daß er sich nicht vertut. Man könnte ihm aber helfen und ganz zum Schluß 2 kleine Buttons anzeigen, die er drücken muß : "alles speichern" und "alles rückgängig machen". Was passiert jetzt im Fehlerfall mit den 100 Positionen bzw. im Programm ? In dem OnClick des einen Buttons steht einfach Transaction.Commit; Alles wird gespeichert und fertig. In dem zweiten steht Transaction.Rollback; Alle Änderungen seit dem Start der Transaction werden rückgängig gemacht. Egal welche Tabelle es betrifft. Äußerst wichtig ist hierbei der Startzeitpunkt der Transaktion bzw. wann committed wird !! Vergesse ich nämlich nach vollendeter Eingabe zu committen, gebe noch 10 Rechnungen ein und dann die eine falsche, dann geht das nicht mehr so einfach. Ein Rollback würde nicht nur die falsche rückgängig machen, sondern auch die richtigen !! Und aus solcherlei Gründen sollte man auch immer die Transactions möglich kurz halten. Die Lesevorgänge getrennt von den schreibenden in Transactions zu kapseln ist auch gut. Allerdings ist es nur echt wichtig, falls jemand DBgrids usw. für Anzeige- und für Eingabezwecke verwendet. |
Re: IB-Transaktionen
Zitat:
Transaktionen werden gestartet. Anschliessend können Änderungen an den Datenbankrecords gemacht werden, soviele wie nötig. Erst durch ein Commit werden diese Änderungen auch für die anderen User in der DB sichtbar, rsp. durch ein Rollback werden die Änderungen komplett verworfen. In der Session, wo du eine Transaktion startest, siehst du auch sofort die Änderungen. Fügst du also einen Datensatzu ein, ist der für dich auch gleich sichtbar, für die anderen im Netz nicht. Nicht alle Datenbanksysteme unterstützen Transaktionen, auch nicht wenn sie als Aushängeschild Mehrbenutzerfähigkeit haben. Ich brauch da nur MySQL zu nennen. Lediglich der Tabellentyp InnoDB bietet Transaktionen an, der Standardtyp und auch der einzige, der in der Anwendung keine Lizenzen erfordert, ist MyIsam. Aber das nur am Rande. Alle Großen (Oracle, MSSQL...) unterstützen selbstverständlich Transaktionen. |
Re: IB-Transaktionen
Zitat:
MySQL kann ab Version 4.x (ich weiss die genaue Version nicht) Transaktionen. MfG André |
Re: IB-Transaktionen
Zitat:
Zitat:
|
Re: IB-Transaktionen
Zitat:
Wie Du nun den Umgang mit den Transaction gestalltest, hast Du hier ja nun gelesen. Es muß also jeder die für sich beste Variante finden. |
Re: IB-Transaktionen
Kurz gesagt eine Transaktion ist immer dann sinnvoll wenn daten an mehreren Datensäten gleichzeitig gemacht werden müssen, egal ob einzel- oder Mehrplatzsystem. Wenn nähmlich durch einen Fehler nur an einem Datensatzt die Änderungen gespeichert werden und am anderen nicht ist die DB inkonsistent. Also das was hier schon öfter gesagt wurde Alles oder Nichts.
@Albi: Sorry, mir ist aber immer noch nicht der Sinn klar warum getrennte Transaktionen fürs lesen und schreiben. :wall: Was mir klar ist, ist das die Transaktionen so kurz wie möglich sein sollten und vieleicht mache ich in meiner Anwendung ja auch was falsch oder zu mindes unschön. Weil ich hier ja auch noch was lernen will mal alles ganz lagsam zum mitschreiben -Transaktion 1 wird gestartet -Daten wedern gelesen -Transaktion 1 wird beendet -Daten werden bearbeitet -Transaktion 2 wird gestartet -Daten werden geschrieben -Transaktion wird beendet Habe ich das soweit richtig verstanden? |
Re: IB-Transaktionen
Danke an Euch alle für die vielen Tips und Erklärungen. Im Prinzip hab ich es nun Dank Eurer Mithilfe begriffen.
Nochmals vielen lieben Dank, Jochen |
Re: IB-Transaktionen
Zitat:
|
Re: IB-Transaktionen
Die Datenänderung erfolgt beim COMMIT.
André |
Re: IB-Transaktionen
@Jelly: Das würde aber bedeuten, das es unbedingt eine Transaktion für lesen und schreiben sein müßte. (Oder habe ich heute ein Brett vor dem Kopf? :wall: ) Ich verstehe das nicht mit den getrennten Transaktione fürs lesen und schreiben. :gruebel: Beides in einer Transaktion zu machen ist mir schon klar.
|
Re: IB-Transaktionen
hallo quake,
mann muss keine zwei transaktionen machen. ich mache aber auch immer zwei einmal für's lesen und eine für's schreiben. ist meiner meinung nach übersichtlicher. raik edit // dicke finger kleine tasten |
Re: IB-Transaktionen
Man kann 2 Transaktionen nehmen. 1 zum lesen, denn auch jeder Lesezugriff braucht, wegen der Multigenerationsarchitektur, eine Transaktion. Wenn du ein COMMIT machst ist die Anzeige deiner daten in den DB Aware Komponenten weg. Deshalb eine zwiete für die Updates.
André |
Re: IB-Transaktionen
Das man 2 Transaktionen verwenden kann ist mir nun klar aber warum?
Wenn ich mir Albis Beitrag anschaue get es aber (indirekt). -Transaktion 1 starten -Daten auslesen per Query -Daten in Edit kopieren (nicht DBEdit) -Transaktion 1 beenden -Daten im Edit ändern -Transaktion 2 starten -Daten aus Edit auslesen und einer SP oder SQL-Update übergeben -Transaktion 2 beenden @kiar: Ich will ja hier was lernen, aber mir leuchtet immer noch nicht ein warum das Übersichtlicher ist. Ich habe eine IBDatabase dieser weise ich eine DefaultIBTransaktion zu. Dann nehme ich eine IBQuary, IBTable oder IBSQL und weise ihnen die Database incl. Transaktion zu. Was ist jetzt aber unübersichtlich? Oder... lasst ihr zumindest Transaktion 1 in meiner Aufzählung länger geöffnet, macht sie also nicht sofort nach dem lesen wieder zu? Dann währe es für mich verständlicher. |
Re: IB-Transaktionen
hallo quake,
ist bei ne kleine app auch richtig, aber gehen wir doch mal von einer app aus die aus zb 5 datamodulen besteht und ihre daten aus ca.30 tabellen raussammelt? da dient jede genaue bezeichnung der übersichtlichkeit. raik |
Re: IB-Transaktionen
Es spielt keine Rolle ob du 1 oder 2 Transaktionen für lesen und schreiben verwendest. Wenn Du aber die Sperrmechanismen der IB nutzt wirst Du merken, da du diese mit per Hand/Code verwalten must.
Bsp. Nehmen wir an du hast 5 User und du benutzt den IdleTimer und hast den Trans-Editor auf "write consistency" gesetzt. Dann must du dich darum kümmern, den IdleTimer wieder zurückzusetzen, da ansonsten nach einer bestimmten Zeit die Daten gespeichert o. verloren gehen. Vergiesst Du den Schreibschutz rauszunehmen stehen die anderen User auf dem Schlauch, da sie an die Daten nicht rankommen, da Du ja noch einen X-Lock auf der DB hast. Aus diesem Grunde habe ich 2 Transactionen, eine zum lesen und eine zum schreiben, einfach nur um die Fehler gleich im Vorfeld auzuschließen. Ich gehe damit sogar noch weiter, ich fülle in meinem Prog CBoxen mit Werten aus der DB und sogar dafür habe ich meine eigene Transaction. Es geht hier also nicht um sinnvoll oder nicht sinnvoll, sondern vorrangig - in meinem Fall - Fehler in der Programmierung zu vermeiden. Wenn es dir besser gefällt Quake, dann kannst Du weiterhin nur eine Transaction für jedes Form nehmen. Das ist in meinen Augen auch kein Problem, wie schon gesagt, muss das jeder für sich entscheiden ob er es braucht oder nicht. Ich habe mir diese nur aus einem Buch abgeschaut und komme so gut damit zu recht. Zitat:
Zitat:
|
Re: IB-Transaktionen
Zitat:
|
Re: IB-Transaktionen
Vielleicht mal ein Beispiel aus meinem Prog, so wie das handhabe.
Im DM liegen 1 Trans-read, 1 Trans-write, 1 Trans-CBoxen (wird auch in anderen Form verwendet), 1 SP, 1 Query. - ich melde mich - öffnen Form (onCreate CBoxen füllen [Trans-CBoxen öffnen & nach füllen gleich wieder schließen]) - in Edit1 was eintragen suchen klicken - Trans-read öffnen - Anfrage an DB schicken - Ergebnis > 0 Trans-read bleibt Active - Daten in die Edit eintragen - Daten ändern - Speichern klicken - Trans-read schließen - Trans-write öffnen - Daten an DB senden - Trans-reaf öffnen um die geänderten Daten aus DB zu holen So sieht mein Schema im groben aus. |
Re: IB-Transaktionen
Tja, muss dann doch noch mal zu den Transaktionen nachfragen.
Nachdem ich wie unten beschrieben meine Daten in den SQL-Server schreibe
Delphi-Quellcode:
kann ein zweiter Client die so vorgenommenen Änderungen nicht sehen. Erst nach erneutem Abmelden von der Datenbank siend dort dann die geänderten Daten zu sehen.
if DM.IBTransaction.InTransaction then
DM.IBTransaction.CommitRetaining; //usw Ist bestimmt eine blöde Frage - aber wie aktualisiere ich denn die Interbase-Tabelle. Blosses Schließen und Öffnen bleibt ohne Wirkung. Bin tatsächlich etwas ratlos. mfg Jochen |
Re: IB-Transaktionen
Wer hat Dir denn das mit dem "CommitRetaining" erzählt ? :shock:
|
Re: IB-Transaktionen
Tag Hansa,
nun, ich denke das diese Variante dazu gedacht ist, ein Commit auf die DB zu machen sie aber nicht zu schließen. Hab ich hier im Forum gefunden. Die Änderungen werden ja auch für andere Anwendungen, wie z.B. die IB-Console in der DB sichtbar, nur nicht in einem zweiten Client von mir. |
Re: IB-Transaktionen
hallo hajo,
arbeitest du mit den zeos? lass einfach mal das Retaining weg , also einfach commit raik |
Re: IB-Transaktionen
hallo kiar,
nein, ich arbeite mit den Interbase-Komponenten von Delphi7 Gruß Jochen |
Re: IB-Transaktionen
dann mache einen harten commit
|
Re: IB-Transaktionen
Hier mal eine kurzer Ausschnitt aus meinem schlauen Buch. :mrgreen:
Zitat:
Um die aktuelle Datenmenge aus der DB zu erhalten mach ein Commit und öffne danach die Transaction und sende ggf. eine neue Abfrage an die DB, dann sollten deine Daten auf dem neusten Stand sein. |
Re: IB-Transaktionen
wie heisst eigentlich das schlaue Buch ?
Dankeschön ! |
Re: IB-Transaktionen
Ich glaube er meint das Buch "InterBase Datenbankentwicklung mit Delphi "von Andreas Kosch zum Thema IBX.
MfG André |
Re: IB-Transaktionen
[quote="Albi"]
Zitat:
Ein CommitRetaining verwende ich zumindest nicht. Das ist irgendwie nichts halbes und nichts ganzes. |
Re: IB-Transaktionen
Da steht aber geschrieben verwirft die Abfragen (SELECT) und nicht die Änderungen (Update). Wenn du also eine Abfrage startest (SELECT) und dann Commitest hast du danach keine Ergebnismenge mehr.
Gegen ein CommitRetain spricht doch nur der Garbage Collector. |
Re: IB-Transaktionen
wegen der MGA muss immer eine Transaktion ausgeführt werden, wenn man Daten lesen und anzeigen will.
Wenn du ein COMMIT machst siehst du in einem DBEdit nichts mehr. André |
Re: IB-Transaktionen
@HaJO: Ruf mal den Transaktions-Editor auf. Evtl steht deine Transaktion auf Schnappschuss.
@André: Das meinte ich auch so. :thumb: |
Re: IB-Transaktionen
Ich meine doch mit irreführend das Wort "verwerfen". Mit einem Commit wird nichts verworfen. Es wird dauerhaft gespeichert und fertig. Entweder es soll was gespeichert werden oder eben nicht. Ich hätte jedenfalls keine Lust, nach einem Stromausfall 100 Transaktionen zu sehen mit der Frage "Soll Transaktion x jetzt committed werden oder doch nicht ? J/N".
|
Re: IB-Transaktionen
Danke nochmals an Euch alle. Aber scheinbar ist es ein Fehler innerhalb der Interbase-Komponenten die in Delphi7 verwendet werden.
Dort steht in der Hilfe zur IBTransaction folgendes: ---------- Die Methode CommitRetaining schließt die aktuelle Transaktion unter Beibehaltung des Transaktionskontextes. Delphi-Syntax: procedure CommitRetaining; C++ Syntax: void __fastcall CommitRetaining(void) Beschreibung Mit CommitRetaining können Sie alle in der aktuellen Transaktion aktualisierten, eingefügten und gelöschten Daten in die Datenbank eintragen und den Transaktionskontext erhalten. Die aktuelle Transaktion ist die zuletzt mit der Methode StartTransaction gestartete Transaktion. Hinweis: Prüfen Sie erst den Status der Eigenschaft InTransaction, bevor Sie CommitRetaining aufrufen. Wenn in der Anwendung keine aktuelle Transaktion vorhanden ist, wird eine Exception ausgelöst. ----------- wäre ja zu schön gewesen wenn es funktioniert hätte. Mit einem richtigen Commit geht alles. Lieben Gruß Jochen |
Re: IB-Transaktionen
Hallo HaJo,
wo ist da der Fehler, es stimmt doch was da geschrieben ist. Über ein SoftCommit können die Daten in die DB geschrieben werden und die Trans wird geschlossen und von dieser eine neue Instanz geöffnet und die Datenmenge der 1ten Trans wird erhalten (alte Version der Datenmenge). |
Re: IB-Transaktionen
Hallo Micha,
ist alles gut und schön was da steht. Die Daten werden ja in die DB geschrieben. Andere Clienets sehen diese Daten dann auch. Aber derjenige Client der geschrieben hat wird niemals mehr aktuelle Daten sehen, die ein anderer Client in die DB geschrieben hat. Nicht einmal dann, wenn die entsprechende Tabelle oder der Query explizit geschlossen und wieder geöffnet wird. Es bleiben dann für diesen Client "nur" seine eigenen Daten sichtbar. Das das korrekt ist, kann ich mir nicht vorstellen! Lieben Gruß Jochen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz