![]() |
Datenbank: Firebird • Version: 2.x • Zugriff über: TIB-Komponenten
Firebird, TIBDataset Löschanweisungen unsichtbar
Hiho,
Ich erzeuge eine TIBDatabase, eine TIBTransaction und ein TIBDataset. Im TIBDataset steht sowas wie 'select * from Daten'. Ich öffne das TIBDataset, lese alle Zeilen ein, merke mir die IDs, schließe das TIBDataset und dann baue ich mir aus den gemerkten IDs ein Delete-Statement zusammen:
Delphi-Quellcode:
Beim 1. Aufruf werden alle Zeilen eingelesen, das Delete-Statement gebastelt und alle Zeilen gelöscht. Toll.
const
szDelete = 'Delete from %s where ID in (%s)'; var sData: string; sDeleteList: string; begin fQuery.Dataset.Active := True; // fQuery ist ein privates Feld einer 'TFoobarQuery', die widerum das TIBDataset kapselt sDeleteList := ''; try fQuery.Dataset.First; while not fQuery.Dataset.Eof do begin sDeleteList := sDeleteList + VarToStr (fQuery.Dataset['ID']) + ','; fQuery.Dataset.Next; end; finally fQuery.Dataset.Active := False; if sDeleteList <> '' then begin SetLength(sDeleteList, Length(sDeleteList) - 1); fConnection.Execute(Format(szDelete, [fTableName, sDeleteList])); // fConnection ist eine TFoobarConnection, die end; // eine TIBDatabase kapselt. end; end; ... procedure TConnection.Execute(const sSQL: string); var cmd: TIBScript; begin cmd := TIBScript.Create(nil); try fTransaction.StartTransaction; try cmd.Database := fDatabase; cmd.Script.Text := sSQL; cmd.ExecuteScript; fTransaction.Commit; except fTransaction.Rollback; raise; end; finally cmd.Free; end; end; Nun füge ich eine Zeile ein und rufe die o.g. Routine nochmal auf. Was soll ich sagen, das Dataset enthält die selben Daten, wie eben, obwohl die gelöscht sind (per IBExpert nachgeschaut). Wie muss ich das anstellen, das so etwas Einfaches funktioniert, also das beim 2.Lesen mal zur Abwechslung andere Daten im Dateset stehen? Danke und Grüße |
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Kann das ein Problem mit den Transaktionen sein? Dein Dataset nutzt wohl eine andere Transaktion wie das Lösch-Statement. Wenn die Transaktion der Dataset nicht beendet wurde und der Isolation-Level auf RepeatableRead steht, dann sollten wohl immer die gleichen gleichen Daten gelesen werden. Hilt es hier, auf ReadCommited zu gehen bzw. die auch das Lesen in expliziten Transaktionen zu starten?
(Kann's momentan nicht testen, drum nur Vermutungen) Grüße, Uli |
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Es sieht wohl eher so aus, als ob die Daten noch im Cache gehalten werden.
Mit ReQuery müsste man eigentlich eine neue Abfrage erzwingen können. |
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
ULIK: Dataset und Skript verwenden die gleiche Transaktion. Den Isolation Level kann ich nicht einstellen.
Sir Rufo: Wie führt man mit einem TIBDataset ein 'ReQuery' aus? Bei IBExpert muss ich selbst SELECT-Anweisungen ('Data'-Tab in der Tabellenansicht) committen, um Änderungen sichtbar zu machen. Kann es sein, das das hier fehlt? Wieso muss man eigentlich SELECT-Anweisungen committen? :gruebel: |
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Zitat:
Der Skriptkomponente wird keine Transaktion zugewiesen, damit erzeugt diese sich temporär eine eigene. Auch das Lesen der Daten startet eine Datenbanktransaktion. So lange diese nicht abgeschlossen ist, wirst du innerhalb dieser Transaktion immer die Daten erhalten, die zum Zeitpunkt des Transaktionsstarts gültig waren oder innerhalb der Transaktion verändert wurden. Solange nur Daten gelesen werden, ist es egal ob mit Commit oder Rollback beendet wird. Natürlich alles abhängig von der Art der Isolation... ![]() |
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Hi Blup,
Danke für die Info: Ich kann das jetzt nicht testen (bin auf Arbeit), aber das könnte es wirklich sein (Skript/Transaktion). Muss ich ein eigentlich ein 'SELECT' explizit mit einem 'StartTransaction/Commit' umschließen? Ich möchte solche Aktionen (SELECT, DELETE usw.) gerne vollständig kapseln und reentrant gestaltent, das also z.B. der Aufruf einer 'Select'-Methode nicht zu einem 'Transaktion ist noch offen' führt, was hier auch passiert ist. Entschuldigt meine Unkenntnis, aber mit Firebird/TIBxxxx-Komponenten hab ich bisher nicht gearbeitet, sondern immer nur mit ADO, wo Transaktionen explizit angestoßen werden. |
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
@Alzaimar : in Deinem Alter sollte man sich mal so langsam mit Multi-Generationen-Architektur beschäftigen. :mrgreen: Damit man nicht wirklich jedes select umständlich mit StartTransaction-Commit/Rollback umschließen muss, gibts ja die Transaction-Isolation-Levels. Z.B. read_commited
|
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Transaktionsisolation hat imho recht wenig mit MGA zu tun.
|
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Hurra! Ich habe es geschafft! Ein Programm, das funktioniert!
Isolation Level eingestellt, dem Skript die gleiche Transaktion verpasst und :spin2: Etwas schade allerdings, das eine so wichtige Eigenschaft wie 'Isolation Level' in der undokumentierten Params-Eigenschaft versteckt ist. Na ja, IB ist eben nur etwas für wahre Männer. Danke für die sachliche Hilfe und das Verkneifen fieser Kommentare. :mrgreen: Mein besonderer Dank gilt dem einzig wahren FB/IB Guru: "Uns" Hansa :stupid: . |
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Zitat:
Autotest Ferrari: hakelige Schaltung, schwere Kupplung => Fazit: geilste Karre von Welt Zitat:
|
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Tja IBX ist halt nicht unbedingt das Gelbe vom Ei. Andere Komponenten(sammlungen) lösen das besser
|
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Zitat:
|
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Zitat:
|
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
MGA ist die Implementierung von Transakationen in IB/FB. Es gibt aber auch andere Möglichkeiten, welche andere DBMS nutzen. Für den Anwender ist es egal wie dieses Feature implementiert wurde.
|
Re: Firebird, TIBDataset Löschanweisungen unsichtbar
Moin
Ich habe einen Zweibenutzerbetrieb: Eine Anwendung (A) schreibt Daten in die DB. Dabei werden Events ausgelöst. Die andere Anwendung (B) reagiert auf diese Events, liest die Daten und löscht sie. Das macht sie aber nur dann, wenn sie die Daten per TCP an ein anderes Programm übertragen kann. Wenn da Keiner ist, werden die Events ignoriert, und die DB wächst. Sobald jemand per TCP erreichbar ist, werden die gepufferten Daten übertragen. Das Ganze ist eine Art Messwerte-Puffer, also nix mit MGA, OIT, KBS* oder HWD**. Ich hab das so vor ein paar Wochen so übernommen (*Aussrede* :mrgreen: ). Der Typ, der das verzapft hat, hat IB und dbExpress-Komponenten gemischt, und ich wollte u.A. dbExpress aus der Anwendung rausnehmen. Wenn jemand übrigens eine bessere Idee hat, oder fertige Pattern für solche Puffer vorzuweisen hat, immer her damit. Aber das wäre eine Frage für einen neuen Thread... *KBS: Keinen Blassen Schimmer ** HWD: Hä Watn Dat? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:17 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