Einzelnen Beitrag anzeigen

Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#1

Firebird embedded mit Threads

  Alt 11. Sep 2009, 13:28
Datenbank: Firebird • Version: 2.1 emb • Zugriff über: IBX
Hallo DB-Profis,

folgende Situation:
-------------------

Ich greife mit eigenen Komponenten über eigene SQL-Funktionen auf eine FB-Datenbank zu.
Die SQL-Funktionen fordern aus einem Pool eine (oder mehrere) freie IBSql an, deklarieren eine passende SQL-Klausel, führen sie aus und geben sie zur Freigabe wieder an den Pool zurück.

Bevor der Pool eine freie IBSql herausgibt (und ggf. vorab bei Bedarf eine eine neue erzeugt) wird eine Standard-IBDatabase und IBTransaction zugewiesen.

Das funktioniert auch wunderbar

Nun gibt es aber eine etwas zeitintensive Funktion (TMyComponent.Compare), die 1-2 Sekunden dauern kann und im Ergebnis einiger SQL-Abfragen ein paar Schalter aktiviert bzw. deaktiviert.

Dies wollte ich daher in einem Thread ausführen, damit der Anwender in der Zeit z.B. schon mal weiter tippen kann. Dies führt jedoch zu Problemen, insbesondere zu der Fehlermeldung "invalid request handle".

Werden die SQL-Funktionen im Rahmen eines solchen Threads ausgeführt, muss ich dann wohl statt der Standard-IBDatabase eine Thread-eigene IBDatabase verwenden (soweit ich gelesen habe)...

Überlegung:
-----------

Ich muss also in der Pool-Komponente beim Bereitstellen einer freien IBSql unterscheiden, ob gerade "die Anwendung" oder "ein Thread" für die Aktion zuständig ist.
Das sollte dann in etwa so aussehen:

Delphi-Quellcode:
function TMyPool.IBSql: TIBSql;
var
  IBSql: TIBSql;
  MyThread: TThread;
  MyIBDatabase: TIBDataBase;
begin
  IBSql := FreieOderNeueIBSql;
  MyThread := CurrentThread; // Instanz eines selbst gestarteten Thread ermitteln
  if not Assigned(MyThread) then // Hauptprozess läuft
  begin
    IBSql.Database := StandardIBDatabase;
    IBSql.Transaction := StandardIBTransaction;
  end
  else
  begin // eigener Thread läuft
    MyIBDatabase := TIBDataBase.Create(MyThread);
    MyIBDatabase.StartTransaction;
    IBSql.Database := MyIBDatabase;
    IBSql.Transaction := MyIBDatabase.Transaction;
  end;
  Result := IBSql;
end;
Jetzt meine Fragen:
-------------------

1) Sind so überhaupt Thread-Zugriffe auf eine FB-EMBEDDED-DB möglich oder gibt es vielleicht eine einfachere Lösung?
2) Muss der jeweilige Thread Owner der "neuen IBDatabase" sein (sonst kann ich evtl. auf die Instanzsuche des Thread verzichten und lediglich auswerten, OB ein Thread läuft)?
3) Gibt es eine bessere Möglichkeit, die Thread-Instanz zu ermitteln, als diese in einer eigenen Liste zu sammeln und zu suchen (ich starte die Threads immer selbst)?
4) GetCurrentThread liefert mir immer ein Handle <> 0, auch wenn kein "externer" Thread gestartet wurde (sicher ist das das Handle des Anwendungsprozesses). Wie kann ich erkennen, ob es sich bei dem Handle um eine "extra gestarteten" Thread außerhalb des Hauptprozesses handelt (egal ob von mir gestartet oder z.B. von einer Fremdkomponente) -> CurrentHandleIsNotMainProcess
5) Was bedeutet "Pseudo-Handle" in dem Zusammenhang? Kann ich mit GetCurrentThread eigentlich unterschiedliche Instanzen des gleichen Thread(typs) finden?

Danke
Stahli
  Mit Zitat antworten Zitat