Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird, TIBDataset Löschanweisungen unsichtbar (https://www.delphipraxis.net/126970-firebird-tibdataset-loeschanweisungen-unsichtbar.html)

alzaimar 5. Jan 2009 21:14

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:
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;
Beim 1. Aufruf werden alle Zeilen eingelesen, das Delete-Statement gebastelt und alle Zeilen gelöscht. Toll.
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

ULIK 5. Jan 2009 21:25

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

Sir Rufo 6. Jan 2009 00:27

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.

alzaimar 6. Jan 2009 06:17

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:

Blup 6. Jan 2009 08:24

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Zitat:

Zitat von alzaimar
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:

Offensichtlich verwendet das Script nicht die selbe Transaktion, wie man deinem Quelltext entnehmen kann.
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...
http://de.wikipedia.org/wiki/Isolation_(Datenbank)

alzaimar 6. Jan 2009 09:40

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.

Hansa 6. Jan 2009 12:43

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

mkinzler 6. Jan 2009 13:13

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Transaktionsisolation hat imho recht wenig mit MGA zu tun.

alzaimar 6. Jan 2009 19:08

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: .

Sir Rufo 6. Jan 2009 19:19

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Zitat:

Zitat von alzaimar
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.

Autotest Opel Corsa: hakelige Schaltung, schwere Kupplung => Fazit: scheiß Karre
Autotest Ferrari: hakelige Schaltung, schwere Kupplung => Fazit: geilste Karre von Welt

Zitat:

Zitat von alzaimar
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: .

"fiese Kommentare" ... wir ... NIEMALS ... :mrgreen:

mkinzler 6. Jan 2009 19:20

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Tja IBX ist halt nicht unbedingt das Gelbe vom Ei. Andere Komponenten(sammlungen) lösen das besser

alzaimar 6. Jan 2009 20:57

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Zitat:

Zitat von mkinzler
Tja IBX ist halt nicht unbedingt das Gelbe vom Ei. Andere Komponenten(sammlungen) lösen das besser

Sieht wohl so aus, aber ich brauch die Events und hab kein Bock, Geld auszugeben (noch nicht).

Hansa 7. Jan 2009 00:47

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Zitat:

Zitat von mkinzler
Transaktionsisolation hat imho recht wenig mit MGA zu tun.

Wie, was ? :shock: In FB ist es doch möglich, auf ein und demselben Stand der DB zu bleiben. Selbst wenn noch 100 User mit dem Programm tausende Transaktionen neu erzeugen und der erste 1 Jahr in Urlaub fährt. Na und ? Nach einem Jahr dürfte der Rechner neu aufgebaut sein, weil die OIT voll zuschlägt. "Rechner ist abgestürzt, zuerst wurde er immer langsamer, du warst ja nicht da". :shock: Vielleicht verstehe ich nicht genau, was Alzaimar meint, aber ohne solche Querschläger in Kauf zu nehmen ist es wohl besser, die lesenden Zugriffe aus dem OIT-Krempel rauszuhalten. Genau da schlägt nämlich eventuell die MGA zu. Alzaimar kann selbstverständlich statt dieser Transaction-Isolation gerne im Programm öfters mal Commit StartTransaction etc. schreiben. :mrgreen:

mkinzler 7. Jan 2009 05:39

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.

alzaimar 7. Jan 2009 06:14

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 06:44 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