Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Transaktion innerhalb Transaktion...IBDAC (https://www.delphipraxis.net/166214-transaktion-innerhalb-transaktion-ibdac.html)

haentschman 3. Feb 2012 08:20

Datenbank: Firebird • Version: 2.5 • Zugriff über: IBDAC

Transaktion innerhalb Transaktion...IBDAC
 
Moin alle... :hi:

ich habe ein DBFramework gebastelt was den kompletten Zugriff auf die DB kapselt. Von außen kann ich eine Transaktion erzeugen, committen oder zurücknehmen. Die Transaktion wird als privates Feld des DB Frameworks verwaltet und den Querys zugeordnet.
Bei einfachen Objekten kein Problem. Ich kann von außen steuern wieviele und verschiedene Objekte in einer Transaktion laufen. Jetzt gibt es aber auch Objekte welche in verschiedene Tabellen schreiben. Dazu hatte ich schon in der jeweiligen Prozedure eine Transaktion für das Objekt gemacht.

Wie kann ich eine "globale Transaktion" erzeugen und innerhalb dieser eine zusätzliche laufen lassen. Im Prinzip ist die Frage welche Transaktion ich welcher Query zuordne.

Mögliche Lösung:
Unterscheidung im DB ob FTransaction nil ist und entsprechend die von außen erzeugte Transaktion nutzen oder die innerhalb der Prozedur erzeugte. Ist das sauber ?

Zum Verständnis:
Wenn ich nur 1 einfaches Objekt dem DB Framework übergebe brauche ich von außen keine Transaktion. Wenn ich eine Liste abarbeite hätte ich gern die ganze Liste in einer Transaktion. Deshalb die externe Erzeugung.

Danke für Info´s

Lemmy 3. Feb 2012 08:52

AW: Transaktion innerhalb Transaktion...IBDAC
 
hi,

schwer zu beantworten, wenn man nicht weiß wie dein Framework aufgebaut ist.

An der Stelle die entscheidet bzw. weiß dass Object A in mehrere Tabellen schreibt, müsste entweder eine neue Transaction erzeugen oder eine aus einem Pool holen.

Diese würde ich dann an die entsprechende Speicherfunktion als Parameter übergeben:

Delphi-Quellcode:
procedure SaveData(ATransaction:TIBTransaction=nil);
begin
....
end;
Und wenn ATransaction<>NiL dann diese Transaction nehmen - ohne abschließendes COmmit. Das muss dann außerhalb passieren. Zumindest fällt mir auf die schnelle nichts sinnvolleres ein...

Grüße

exilant 3. Feb 2012 09:32

AW: Transaktion innerhalb Transaktion...IBDAC
 
Also ich mache es in meinem DBOobjekt ähnlich: Ich setze ein Flag (fInTransaction=boolean) und erzeuge eine "objektglobale" Transaktion. Alle ab jetzt vom DBObjekt erzeugten querys/sqlcommands bekommen das "objektglobale" Transaktionsobjekt zugewiesen bis ich sowas wie DBObjekt.commit oder DBObjekt.rollback mache.Dort wird fInTransaction" wieder auf FALSE gesetzt und die Transaktion beendet. Ist das Objekt nicht "InTransaction" dann bekommt jedes erzeugte query/command seine eigene Transaktion. Die wird dann per default im Destruktor commited und freigegeben. Zusätzlich kann ich auch noch trotz gesetztem InTransaction Querys/Commands mit eigenen Transaktionen erzeugen, das benötige ich aber nicht wirklich, wie sich herausgestellt hat. Klappt seit Jahren.

haentschman 3. Feb 2012 11:25

AW: Transaktion innerhalb Transaktion...IBDAC
 
Danke für Eure Anteilnahme...8-)

Es gestaltet sich wahrscheinlich einfacher als gedacht. Folgendermaßen habe ich es gelöst:
einfaches Objekt (Daten für mehrere Tabellen):
- keine Transaktion von außen
- in der Save Prozedur wird eine Transaktion erzeugt und der Query zugeordnet, Commited oder zurückgenommen.

Liste (Objekte mit Daten für mehrere Tabellen)
- in der Connection eine Transaktion starten (Quasi global für die Verbindung)
- Abarbeitung wie einfaches Objekt
- die "globale" Transaktion Commiten oder zurücknehmen.

...so sollte es eigentlich gehen.

DeddyH 3. Feb 2012 12:24

AW: Transaktion innerhalb Transaktion...IBDAC
 
IIRC habe ich das mal so gemacht: sowohl Objekte als auch Listen stammen von einer gemeinsamen Vorfahrklasse ab. Diese besitzt eine Klassenvariable ExplicitTransaction. Soll eine Liste in einer Transaktion abgearbeitet werden, setzt sie diese auf true, arbeitet und setzt sie anschließend zurück. Die Objekte werten die Variable aus und starten bei false selbst eine Transaktion. Das ist vielleicht nicht sonderlich schön, hat aber funktioniert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz