Firebird-Zugriff aus DLL

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
zappa2
Beiträge: 43
Registriert: Do 28. Nov 2013, 09:54

Firebird-Zugriff aus DLL

Beitrag von zappa2 »

Ich rufe aus einer DLL eine StoredProc auf und gebe einen einfachen Integer als Result an den Aufrufer der DLL zurück.
Wenn ich in der DLL die IBConnection connecte bekomme ich im Client (der über eine völlig eigene Connection ebenfalls an dieser DB hängt) diesen Fehler:

Die dll soundso hat Exception EIBDataBaseError ausgelöst mit der Meldung:
IBConn: Rollback (invalid transaction handle; expecting transaction start)

Das Merkwürdige hierbei ist, dass die in der Fehlermeldung genannte IBConn die Connection des Clients ist und nicht die der dll.
Ich habe für meine Tests das Ganze schon mal so abgespeckt, dass ich aus der DLL nur noch einen konstanten Test-Integer (ohne SQL-Abfrage) aus der Auswerteprozedur des Datenmoduls zurückgebe. Solange die Connection zu bleibt ist alles okay; sobald ich die -wie oben schon erwähnt- connecte, ist der Fehler da.

Hat hier jemand evtl. einen Tipp, wo mein Denkfehler liegt?

Oder gibt es evtl. irgendwelche Parameter in der Connection oder Transaction, die für solche Fälle zu de-/aktivieren sind?

zappa2
Beiträge: 43
Registriert: Do 28. Nov 2013, 09:54

Nachtrag

Beitrag von zappa2 »

Ich habe mir das Ganze jetzt mal im IBExpert angeschaut:

Wenn erst mal nur die Anwendung läuft, gibt es in der MON$TRANSACTIONS mehrere Einträge mit der gleichen MON$ATTACHEMENT_ID.

Startet der Aufruf der dll, so kommt unter einer weiteren (nächsten) MON$ATTACHEMENT_ID nochmal die aufrufende EXE mit einer zusätzlichen Transaction dazu. Bis hierhin verstehe ich das auch.

Aber schließe ich nun die Connection der DLL, dann sind auch die Attachments der EXE weg. Und das ist in der Tat so: sämtliche DB-Zugriffe der EXE schlagen nun fehl => keine Connection.

Wo liegt mein Denkfehler?

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Firebird-Zugriff aus DLL

Beitrag von fliegermichl »

Evetuell hängt das mit SharedMem zusammen?

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Firebird-Zugriff aus DLL

Beitrag von af0815 »

Hast du mit dem Firbird Server Manager sehen ob du wirklich 2 Connections bekommst (1x App 1x Dll) oder es nur eine Connection ist, da die App und die Dll im selbst Kontext laufen und du nur eine reale Connection bekommst.

Für mich klingt das stark dannach. Du beantragst beim Treiber eine Connection, nachdem der aber in den selben Adressraum geladen wird, sieht der das bereits eine Connection da ist und fasst die zusammen. Dann wären deine Probleme auch erklärt. Das sieht man aber am besten am Server. Dann könnte ein Ausweg sein, die Transaktionen nicht auf auto zu stellen, sondern selbst zu machen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

zappa2
Beiträge: 43
Registriert: Do 28. Nov 2013, 09:54

Re: Firebird-Zugriff aus DLL

Beitrag von zappa2 »

Erst mal vielen Dank für Eure Antworten!

@fliegermichl: Hängt ShareMem nicht nur mit Strings in der Schnittstelle Exe<=>Dll zusammen? Ich übergebe aber nix an die Dll und bekomme einen Integer zurück, also brauche ich m.E. die ShareMem nicht einbinden. Ich hatte sie aber auch mal eingebunden, geholfen hat es nicht.

@af0815: Ich bekomme definitiv eine zweite Connection:
Wenn ich im Debugger durchsteppe und parallel im IBExpert mir die MON$ATTACHMENTS anschaue:
- man sieht direkt, wie beim Öffnen der Connection ein neuer Eintrag kommt (im Kontext der Exe, nicht der dll),
- sobald ich meine Query starte kommt eine neue Transaction in der MON$TRANSACTIONS mit der neuen Attachment-ID.
- sobald die Query geschlossen und die Transaction committet wird, verschindet die betreffende Zeile aus MON$TRANSACTIONS, der Eintrag in der MON$ATTACHMENTS bleibt.
- sobald ich die Connection der dll schließe, fliegen alle Transactions der Exe aus der MON$TRANSACTIONS raus und
es werden in der MON$ATTACHMENTS beide Zeilen der Exe entfernt => Programmabsturz.

Ich habe nur zu Testzwecken in der Dll mal eine andere Datenbank als in der aufrufenden Exe benutzt. Wenn die de-connected wird, fliegt man trotzdem aus der Connection der aufrufenden Exe raus.

Jetzt mache ich es so, dass ich die Connection der Dll nach dem Aufruf offen lasse, also das Datenmodul auch nicht explizit freigebe.
In diesem Falle scheint alles gut zu sein: Programm läuft weiter mit seiner eigenen Connection, man kann die Dll noch x-mal aufrufen; beim Schließen der Exe sind alle Transactions und Attachments in der Datenbank sauber aufgeräumt
worden.

Aber ich habe ein schlechtes Gefühl dabei, ein erzeugtes Object nicht direkt irgendwann wieder freizugeben, vor allem, eine geöffnete Connection nicht mal irgendwann wieder zu schließen.
Nunmehr macht das wohl alles die Speicherverwaltung von Lazarus - ein dickes Lob an die Entwickler derselben!

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Firebird-Zugriff aus DLL

Beitrag von af0815 »

zappa2 hat geschrieben:Aber ich habe ein schlechtes Gefühl dabei, ein erzeugtes Object nicht direkt irgendwann wieder freizugeben, vor allem, eine geöffnete Connection nicht mal irgendwann wieder zu schließen.
Nunmehr macht das wohl alles die Speicherverwaltung von Lazarus - ein dickes Lob an die Entwickler derselben!

Das Glaube ich dir.

Die Speicherverwaltung arbeitet mit Refernzzählern, bei jeder Refernz auf das Objekt wird der erhöht, wird die Referenz freigegeben,so wird er erniederigt. Wenn der Stand auf 0 geht, so war es die letzte Referenz und das Objekt wird auch freigegeben, soweit so gut.

Was mir fehlt bei deiner Schilderung, das die DLL eine 2te Connection eröffnet (NICHT Transaktion). Die EXE und die DLL benötigen JEDER eine Connection und eine Transaction. Bei dir sieht es so aus als würde die EXE die Connection machen und die DLL diese einfach schliessen.

Du brauchst zwei Einträge mit unterschiedlichen MON$ATTACHEMENT_ID, ohne dem ist das nur eine Connection die Aufgebaut wurde.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

zappa2
Beiträge: 43
Registriert: Do 28. Nov 2013, 09:54

Re: Firebird-Zugriff aus DLL

Beitrag von zappa2 »

Ich denke doch, dass ich das geschrieben habe:

Die erste Connection (also die EXE) bekommt den ersten Eintrag in der MON$ATTACHEMENTS,

die zweite Connection (also die der DLL) bekommt einen zweiten Eintrag mit einer eigenen ID.

Selbstverständlich gehören zu beiden unterschiedlichen MON$ATTACHEMENT_IDs auch unterschiedliche Transactions.

Auch der Hinweis, das der Fehler auch bei unterschiedlicher DB in EXE und DLL bleibt, sagt das indirekt: 2 DB => 2 Connections => 2 MON$ATTACHEMENT_IDs.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Firebird-Zugriff aus DLL

Beitrag von af0815 »

Schon mal versucht die dll zu debuggen ? Nicht die exe, sondern explzit die dll, nicht das dir dort eine Exception das verursacht.

Mehr Ideen habe ich dann nicht mehr.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

zappa2
Beiträge: 43
Registriert: Do 28. Nov 2013, 09:54

Re: Firebird-Zugriff aus DLL

Beitrag von zappa2 »

Ich danke Dir für Deine Hinweise!

Natürlich debugge ich sowohl die EXE als auch die DLL. In der DLL passiert nix, was das Deconnecten der Connection der aufrufenden Exe erklären würde.
Es gibt keine Exception, der Debugger bleibt ohne jegliche Meldung hängen, sobald man die Connection der DLL deaktiviert. Keine Variableninhalte sind mehr abrufbar.

Der derzeitige Weg funktioniert ja, dass ich das Aufräumen der Speicherverwaltung von Lazarus überlasse. Auch im Debugger läuft es so ohne irgendwelche Fehler oder Hinweise o.ä.

Evtl. haben wir es hier mit einem Bug in der Implementation der TIBConnection zu tun? Ich habe das Gleiche im uralten Delphi5 getestet, hier läuft es problemlos.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Firebird-Zugriff aus DLL

Beitrag von af0815 »

Da kann nur mehr ein Minimalbeispiel zum Testen helfen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten