[Erledigt] SQLite: db.ExecSQL(SQL) klappt in 2. Thread nicht

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
SiMoeBoe
Beiträge: 28
Registriert: So 13. Mär 2011, 22:16
OS, Lazarus, FPC: Ubuntu (L 0.9.28.2-10ubuntu1 FPC 2.4.0)

[Erledigt] SQLite: db.ExecSQL(SQL) klappt in 2. Thread nicht

Beitrag von SiMoeBoe »

Hallo Leute,

Derzeit versuche ich aus einem 2. Thread heraus eine tabelle zu einer SQLite Datenbank hinzuzufügen.
Aus irgendeinem Grund klappt dies nicht.
Ich nutze zum Zugriff auf die SQLite treiber und die Datenbank nicht die Lazaruseigenen Komponenten, sondern den Simple Delphi Wrapper von Tim: http://www.itwriting.com/blog/?page_id=659" onclick="window.open(this.href);return false;
Dies liegt v.a. daran, dass das Projekt von Delphi 7PE auf Lazarus umzieht.
Mein Problem ist, dass sich der Thread, in dem auch die Tabelle erstellt werden soll, an eben dieser Stelle aufhängt:

Code: Alles auswählen

if not smbdb.TableExists(pcregname) then    //pcregname & adddir_SQL sind global definierte string-Variablen
  begin
   adddir_SQL := 'CREATE TABLE '+pcregname+' ([Pfad] TEXT,';
   adddir_SQL := adddir_SQL+'[Titel] VARCHAR (255),[Interpret] VARCHAR (255),[Dauer] VARCHAR (25),';
   adddir_SQL := adddir_SQL+'UNIQUE(Pfad));';
   smbdb.ExecSQL(adddir_SQL);                //Fehler.... Synchronize einbauen --> Hilft nicht?!?
  end;
Bis dahin läuft der Thread ohne Probleme.
Wie ihr aus dem Kommentar entnehmen könnt, hat es nicht geholfen, den Aufruf mit einer Procedure als Synchronize aufzurufen.
Der selbe Code klappt innerhalb des Hauptthreads problemlos.
Dass ich, weil die DB woanders versehentlich auch gerade verwendet wird (sie ist aus dem Hauptthread genauso erreichbar) kann ich glaube ich ausschließen, da ja die Frage nach der Tabellenexistenz am Anfang des Threads zu klappen scheint...
Vielleicht hab ich ja irgendwas übersehen und ihr findet eine Lösung..

Unter Delphi und WinXP hat das ganze funktioniert, jetzt soll es eben mit Lazarus und Ubuntu 10.10 auch laufen^^

Ich bitte um Unterstützung.
Vielen Dank,
Euer SiMoeBoe

PS: Ich erhalte keine Fehlermeldungen! Allerdings habe ich auch nur Zugriff auf Fehler, welches mir das Terminal ausgibt, da das Programm aus Lazarus selbst heraus nicht Startbar ist, da ich zwangsweise eine start.sh verwenden muss. Ich kann kompilieren, nicht jedoch den Debugger verwenden.
Zuletzt geändert von SiMoeBoe am Di 19. Jul 2011, 13:59, insgesamt 1-mal geändert.
Woran du glaubst, dafür sollst du leben und sterben.

Benutzeravatar
theo
Beiträge: 10865
Registriert: Mo 11. Sep 2006, 19:01

Re: SQLite: db.ExecSQL(SQL) klappt in 2. Thread nicht

Beitrag von theo »

Bist du unter Linux? Hast du die unit cthreads im *.lpr in die uses an erster Stelle aufgenommen? (Ist da aber ge-ifdef-t)

Socke
Lazarusforum e. V.
Beiträge: 3177
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: SQLite: db.ExecSQL(SQL) klappt in 2. Thread nicht

Beitrag von Socke »

Hast du zwei getrennte Datenbank-Handles für beide Threads (auch wenn es daran nicht liegen sollte)?
Ich kenne die Wrapper, die du verwendest nicht wirklich (auch wenn ich glaube, dass ich mit denen mal gearbeitet habe -- der Screenshot sieht sehr verdächtig aus); sind die multi-thread-fähig? Wie setzt du sie ein?

Noch ein logischer Hinweis:
Streng genommen kann es bei deinem Code passieren, dass dein Thread zwar ermittelt, dass die Tabelle nicht vorhanden ist, diese dann aber von einem anderen Thread angelegt wird, bevor er sie selbst erstellen kann. Daher würde ich CREATE TABLE IF NOT EXISTS "pcregname" (...) empfehlen
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

SiMoeBoe
Beiträge: 28
Registriert: So 13. Mär 2011, 22:16
OS, Lazarus, FPC: Ubuntu (L 0.9.28.2-10ubuntu1 FPC 2.4.0)

Re: SQLite: db.ExecSQL(SQL) klappt in 2. Thread nicht

Beitrag von SiMoeBoe »

Zu theo: Japp, habe ich. Die Initialisation und einiges anderes läuft im Thread auch, erst an der genannten Stelle hängt es sich auf.

Zu Socke: Ich denke schon, dass der Wrapper Multithreadfähig ist, da dieses Projekt unter WinXP und in Delphi 7 PE geschrieben einwandfrei lief.
Was genau meinst du mit eigenem DB_Handle? Wenn ich das richtig interpretiere hab ichs glaube ich nich, weiß aber auch nicht, wie ichs am besten machen sollte.
Die smbdb-Datenbank ist in einer eigenen Unit als Globale Variable definiert und wird auch vom Hauptthread mit verwendet.
Besser gesagt: sie wird im Hauptthread initialisiert und die meisten Abfragen laufen darüber. Nur das Hinzufügen von Datensätzen soll über den Extrathread laufen.
Kann es dadurch zu dem Problem kommen?
Das der Thread im Prinzip wartet, bis der Hauptthread fertig ist, was ja nie geschieht?
Wenn das Programm voll läuft müssen der Hauptthread und 2 (!) weitere Threads unabhängig voneinander Zugriff auf die DB haben.
Wenn dass das Problem ist, würde mich interessieren, warum es unter Delphi lief^^

Naja, vielen Dank schonmal für die Hilfe!!
Viele Grüße,
Euer SiMoeBoe
Woran du glaubst, dafür sollst du leben und sterben.

Socke
Lazarusforum e. V.
Beiträge: 3177
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: SQLite: db.ExecSQL(SQL) klappt in 2. Thread nicht

Beitrag von Socke »

Ein Handle ist ein Objekt einer externen Bibliothek, über das diese weiß, mit welcher Datenbank (im Falle von SQLite) du arbeiten willst.

Wenn du eine programm-globale Variable für deine Verbindung nutzt, kann das zu Fehlern in Verbindung mit Multithreading führen. Ich hab mir gerade den Wrapper (v16) heruntergeladen und gesehen, dass er an sich nicht threadsafe ist. SQLite hingegen kann für sich genommen threadsafe kompiliert und betrieben werden (siehe unter anderem http://www.sqlite.org/threadsafe.html" onclick="window.open(this.href);return false;); wenn du die selbe Bibliotheksdatei (.dll) verwendest wie unter Delphi, liegt das Problem wohl eher nicht bei der Bibliothek.

Vielleicht kannst du ein Minimalbeispiel erstellen, in dem der Fehler ebenso auftritt.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

SiMoeBoe
Beiträge: 28
Registriert: So 13. Mär 2011, 22:16
OS, Lazarus, FPC: Ubuntu (L 0.9.28.2-10ubuntu1 FPC 2.4.0)

Re: SQLite: db.ExecSQL(SQL) klappt in 2. Thread nicht

Beitrag von SiMoeBoe »

Ein Beispielprojekt erstellen klingt gut; Das müsste helfen.
Werd ich aber erst heute Abend zu kommen, ich schicks dann hier, oder sag, wenn ich den Fehler habe.

An der Bibliothek liegts glaub ich wirklich nicht, sondern an irgend einer Stelle in meinem Code..
Naja, mal schauen..

Viele Grüße und Danke,
SiMoeBoe
Woran du glaubst, dafür sollst du leben und sterben.

SiMoeBoe
Beiträge: 28
Registriert: So 13. Mär 2011, 22:16
OS, Lazarus, FPC: Ubuntu (L 0.9.28.2-10ubuntu1 FPC 2.4.0)

Re: SQLite: db.ExecSQL(SQL) klappt in 2. Thread nicht

Beitrag von SiMoeBoe »

Hallo Leute,
Nach langer Zeit, in der ich durch Abitur, Arbeit und andere Nebensächlichkeiten vom Programmieren fern gehalten worden bin,
hab ich heute überraschend schnell den Fehler gefunden.
Die Variable 'pcregname' enthält den 'Namen' des Rechners.
Nun hatte dieser bei mir aber einen Bindestrich enthalten, was natürlich jedesmal zu einem Fehler in der MySQL-Abfrage führte *HandAnStirnKlatsch* :oops:

Nachdem ich dies geändert habe, klappt diese Stelle endlich und ich kann weiterarbeiten.

Derzeit suche ich nach einer besseren Möglichkeit, einen PC relativ eindeutig zu identifizieren, aber das ist ein anderes Problem^^

Vielen Dank für eure Hilfe,
Euer SiMoeBoe
Woran du glaubst, dafür sollst du leben und sterben.

Antworten