Transaktionen: Commit vs. CommitRetaining (Firebird/Interbase)



  • Ich würde bei IB / FB trotrdem Commit empfehlen.

    CommitRetaining muss mit sehr großer Vorsicht genossen werden! Bei der Transaktionssteuerung in IB/FB passiert folgendes: Jede Transaktion erhält eine eindeutige Transaktionsnummer. Durch die Multigenerationenarchitektur von IB/FB erhält die Transaktion dann Zugriff auf eine "Kopie" des Datenbestandes, der zum Zeitpunkt des Startes der Transaktion gültig war. Wird diese Transaktion jetzt eine zeitlang mit CommitRetaining bearbeitet, passiert folgendes: Es werden von anderen Clients immer weitere Transaktionen gestartet. Somit steigt der Unterschied zwischen unserer Transaktion (oldest active transaction) und der neuesten Transaktion immer weiter an. Das muss IB/FB aber verwalten, was Systemressourcen und damit Performance benötigt.



  • Das ist wie bei vielem andern nicht grundsätzlich richtig
    oder falsch ;). Es hängt eben davon ab, was man mit der Datenbank gerade macht. Wieviel Nutzer gleichzeitig arbeiten ... usw.

    Vielleicht so:
    CommitRetaining kann dem Programmierer einiges Arbeit erleichtern (besonders bei Datenmengen ), was aber auf Kosten des Servers passiert :D.

    Also nicht immer und überall aber dort wo es mir hilft. Ansonsten immer interresant
    "The Firebird Book" von Helen Borrie.



  • Bevor ich mir jetzt das Buch bersogen und lesen muss...

    Ich habe bisher überhaupt keine Vorteile bei CommitRetaining entdecken können. Hilf mir doch mal aus der Wissenlücke.



  • Nichts leichter als das.

    Was passiert nach einem hard commit (COMMIT) mit allen datensensitiven Steuerlementen ? Sie sind leer 😞 .
    Beim soft commit (CommitRetaining) bleibt der Transaktionskontext erhalten und ich habe weiter meinen eben bearbeiteten Datensatz im Formular oder Grid. In beiden fällen ist meine Änderung aber für andere Transaktionen (Benutzer) sichtbar.

    Wenn ich zum Beispiel ein DBGrid habe und dort Änderungen druchführe, welche ich in der Datenbank "committen" will damit alle anderen User im Netz die Änderung sehen können, so muß ich nach einem hard commit selber den Dataset manuell wieder öffnen und auf den aktuellen Datensatz navigieren (den ich mir natürlich vorher gemerkt habe ) um im DBGrid weiterarbeiten zu können.

    Mit einem soft commit ist das eben nicht notwendig. Für den Programierer entfällt der Aufwand des Wiederöffens und Synchronisierens der Datenmenge. Auf dem Bildschirm bleibt alles wie es war.

    Verständlich ?



  • Ok, das macht Sinn.

    Kann ich bei mir aber nicht einsetzen. Ich hab keine SELECTs in meinen Programmen, die Daten nur aus einer einzigen Tabelle beziehen... Da muss ich den 'umständlichen' Weg über INSERT- und UPDATE-Statements gehen. Und dann ergo auch die Datenquelle neu öffnen und positionieren.

    Bedankt.



  • Das bezieht sich nicht auf einzelne Tabellen, sondern auf den Transaktionskontext.
    Ob deine SQL- Statements 1 oder 10 Tabellen beinhalten ist egal.
    IBDataset kapselt ja gerade die Datenbankzugriffe für die Steuerelemente.
    Für aufwendigeren Datenbankanwendungen würde ich aber auf andere DB Komponenten (z.B. FIBplus usw.) wechseln.

    Viel Spass noch 😉



  • AFAIR sind Ergebnismengen, die sich aus mehreren Tabellen zusammensetzen grundsätzlich schreibgeschützt... Wo mach ich den Denkfehler?

    Ich hab bis vor kurzem fast auschließlich die Kombination BDE / informix verwendet Da ich jetzt aber vermehrt Firebird einsetzen werde, habe ich mir die IBObjects-Komponenten zugelegt. Bin aber noch dabei mich in die Internas einzuarbeiten... Ist ja doch etwas ganz anderes.

    @Mods: Sorry, wenn das zu OT wird, bitte kurze Info.





  • Hallo,

    so jetzt hau ich das hier nochmal rein,
    also Primärschlüssel ist die ID (vom type char da ich net mehr als 255 Datensätze erwarte und dafür 1 Byte reicht) und wird beim erzeugen der Tabelle angelegt.

    Wenn ich das Refresh() weglasse kann ich mir au das RefreshSQL-SQL-Statement sparen! Richtig?

    Das is doch alles blöd wenn ich nen Datensatz ändere und dann CommitRetaining() nutze (damit es aktualisiert wird ohne die Transaktion zu beenden und damit der Datensatzzeiger auf der aktuellen Position bleibt) und dann trotzdem:

    void __fastcall TForm1::IBDataSet1AfterPost(TDataSet *DataSet)
    {
       IBDataSet1->Active = false;
       IBDataSet1->Active = true;
    }
    

    aufrufen muß um den Datensatz im DBGrid richtig einsortieren zu lassen wobei mein Datensatzzeiger wider auf die erste Position fällt!
    Ergo: Für mich ist Commit=CommitRetaining da ich nach beiden den Datensatzzeiger wieder Händisch auf die aktuelle Position setzen muß!

    Habe jetzt schon 2 Fachbücher durchsucht aber keine tolle andere Lösung gefunden um mein DBGrid auf den aktuellen zu halten! Hat vielleicht net jemand nen anderen Vorschlag???? 😞

    Es muß da doch was geben da es bei IBTable au die tolle Funktion IndexName() gibt und IBTable doch IBDataSet untergeordnet is!
    Die Funktion IndexName gibt es laut Hilfe in der Klasse TCustomClientDataSet die ja von IBDataSet abgeleitet sein müßte oder??? 🙄

    Also am beste wär es für mich wenn ich irgendwie das IndexName von TCustomClientDataSet benutzen könnte aber ka ob und wie ich das auf mein IBDataSet beziehen kann!!! 😕

    Danke



  • hansi hinterseer schrieb:

    Hallo,

    so jetzt hau ich das hier nochmal rein,
    also Primärschlüssel ist die ID (vom type char da ich net mehr als 255 Datensätze erwarte und dafür 1 Byte reicht) und wird beim erzeugen der Tabelle angelegt.

    Ich würde den PK nicht als Char(1) anlegen. Warum ?
    Weil ich nur mit Int oder BigInt einen Generator benutzen kann,
    welcher mir einen eindeutigen PK automatisch erzeugen kann (im Tabellen-Trigger before insert). Die ca. 8kbyte Festplattenplatz (bei 255 Datensätzen) "verschwende" ich dafür gerne.
    Der PK wird beim Insert erzeugt und nicht beim anlegen der Tabelle 😉 .

    hansi hinterseer schrieb:

    Das is doch alles blöd wenn ich nen Datensatz ändere und dann CommitRetaining() nutze (damit es aktualisiert wird ohne die Transaktion zu beenden und damit der Datensatzzeiger auf der aktuellen Position bleibt) und dann trotzdem:

    void __fastcall TForm1::IBDataSet1AfterPost(TDataSet *DataSet)
    {
       IBDataSet1->Active = false;
       IBDataSet1->Active = true;
    }
    

    aufrufen muß um den Datensatz im DBGrid richtig einsortieren zu lassen wobei mein Datensatzzeiger wider auf die erste Position fällt!
    Ergo: Für mich ist Commit=CommitRetaining da ich nach beiden den Datensatzzeiger wieder Händisch auf die aktuelle Position setzen muß!

    Ist leider richtig beim DBGrid. Ist doch aber auch nicht so auwendig. Man merk sich den PK und dann ein gepflegtes locate(...

    hansi hinterseer schrieb:

    Es muß da doch was geben da es bei IBTable au die tolle Funktion IndexName() gibt und IBTable doch IBDataSet untergeordnet is!
    Die Funktion IndexName gibt es laut Hilfe in der Klasse TCustomClientDataSet die ja von IBDataSet abgeleitet sein müßte oder??? 🙄

    IBTable und IBDataSet haben den selben Vorfahren (IBCustomDataSet ) und sind nicht voneinander abgeleitet.
    Vielleicht nochmal einen Blick ins OOP-Buch ? 😉

    TCustomClientDataSet ist was ganz anderes (siehe Hilfe)


Anmelden zum Antworten