Delete mit SQLite3 - Database locked

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Poelser
Beiträge: 55
Registriert: Do 6. Nov 2008, 14:16
OS, Lazarus, FPC: Windows Vista (L 1.0.6 FPC 2.6.0)
CPU-Target: Intel 32 Bit/Arm

Delete mit SQLite3 - Database locked

Beitrag von Poelser »

Moin,

mal wieder ein Problem mit SQLite3, diesmal nicht nur WINCE, sondern auch Win32:

Dieser Codeteil geht problemlos durch:

Code: Alles auswählen

DM.con1.ExecuteDirect('DELETE FROM patdiaetkz WHERE fAufID=' + IntToStr(aufid));
  DM.con1.Transaction.Commit;
Und dieser hier nicht:

Code: Alles auswählen

DM.con1.ExecuteDirect('DELETE FROM kobestellung WHERE fmebestid IN (' + tmps + ')');
  DM.con1.Transaction.Commit;
Ich bekomme beim Commit einen Fehler "Database locked". Im Netz konnte ich wenigstens ein paar Bruchstücke finden, die auf Probleme von SQLite3 hinweisen, so richtig was Konkretes ist aber leider nicht dabei. Was kann denn hier die Ursache sein?

Das Löschen von Datensätzen mit TSQLQuery/DeleteSQL bekomme ich leider auch nicht hin, da bräuchte ich mal 'nen funktionierenden Codeschnipsel... :wink:

CU, der Poelser

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Delete mit SQLite3 - Database locked

Beitrag von mse »

Poelser hat geschrieben: Ich bekomme beim Commit einen Fehler "Database locked". Im Netz konnte ich wenigstens ein paar Bruchstücke finden, die auf Probleme von SQLite3 hinweisen, so richtig was Konkretes ist aber leider nicht dabei. Was kann denn hier die Ursache sein?
Du arbeitest mit SQLDB?
Ist eine select Operation auf kobestellung noch nicht abgeschlossen, d.h noch nicht all records in die Query-Komponente übertragen? Wenn ich mich recht erinnere, hält SQLite3 einen Lock vom ersten aufruf sqlite3_step() bis alle rows abgeholt wurden. Setze tmsesqlquery.packetrecords auf -1 damit beim öffnen der query alle Daten geladen werden (MSEgui, bei Lazarus wird es ähnlich sein).
Das Löschen von Datensätzen mit TSQLQuery/DeleteSQL bekomme ich leider auch nicht hin, da bräuchte ich mal 'nen funktionierenden Codeschnipsel... :wink:
Falls die Tabelle einen primary key hat ist kein code notwendig, da DeleteSQL automatisch gebildet wird. Also:

Code: Alles auswählen

 
query.delete;
query.applyupdates;
transaction.commit;
 

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Delete mit SQLite3 - Database locked

Beitrag von Christian »

SQlite hat unterschiedliche sperren für lesenden und schreibenden Zugriff. Ein anderes Programm oder eine andere Query ist noch damit beschäftigt in die Datenbank zu schreiben während du das ausführst.
TMSEQuery gibts in SQLdb und Lazarus übrigends nicht ;)
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Delete mit SQLite3 - Database locked

Beitrag von mse »

Christian hat geschrieben: Ein anderes Programm oder eine andere Query ist noch damit beschäftigt in die Datenbank zu schreiben während du das ausführst.
Das ist glaube ich nicht ganz korrekt. Wenn ich mich recht erinnere, braucht SQLite3 zum committen einen exklusiven lock, den kann es auch nicht erhalten, solange noch ein nicht abgeschlossener data fetch läuft.
TMSEQuery gibts in SQLdb und Lazarus übrigends nicht ;)
TMSEQuery gibts in MSEgui auch nicht, die Komponente heisst dort tmsesqlquery und ist ein fork der TSQLQuery, beruhend auf einer komplett neugeschriebenen TBufDataset Komponente, welche lokale Indizes hat und die Möglichkeit eines Logfiles zur laufenden Aufzeichnung der Editvorgänge bietet. Dadurch kann die Verbindung zum Datenbankserver nach dem Download unterbrochen oder sogar die Applikation geschlossen werden. Später wird die Verbindung wieder hergestellt und die geänderten Datensätze werden übertragen. Ein weiterer Betriebsmodus von tmsebufdataset arbeitet ohne Datenbankverbindung und ohne Logfile. Damit erhält man ein in memory Dataset mit dem vollen Funktionsumfang, welches zur Zwischenspeicherung von Daten oder zur Darstellung von lokal berechneter Tabellen verwendet werden kann. tmsebufdataset und dadurch auch tmsesqlquery unterstützen auch fkInternalCalc Felder.

Poelser
Beiträge: 55
Registriert: Do 6. Nov 2008, 14:16
OS, Lazarus, FPC: Windows Vista (L 1.0.6 FPC 2.6.0)
CPU-Target: Intel 32 Bit/Arm

Re: Delete mit SQLite3 - Database locked

Beitrag von Poelser »

mse hat geschrieben:
Christian hat geschrieben: Ein anderes Programm oder eine andere Query ist noch damit beschäftigt in die Datenbank zu schreiben während du das ausführst.
Das ist glaube ich nicht ganz korrekt. Wenn ich mich recht erinnere, braucht SQLite3 zum committen einen exklusiven lock, den kann es auch nicht erhalten, solange noch ein nicht abgeschlossener data fetch läuft.
Hmm, ein anderes Programm kann ich ausschließen, eine andere Query ebenfalls. Wenn ich vorweg einen "DM.Query.Close" ausführe bleibt der Fehler bestehen. Die Variante eines Deletes über die Query mit .Delete und .Applyupdates produziert übrigens den gleichen Fehler.

Wenn ich mit den ZEOS-Komponenten arbeite, dann gibt es das Problem übrigens nicht. Die kann ich leider nicht benutzen, weil ich nur zur zur Entwicklungszeit mit Win32 arbeite. Das eigentliche Ziel ist WINCE, mit ZEOS bekomme ich nur nach ein paar Patches etwas compiliert, aber die Anwendung knallt auf dem PDA gleich beim Start weg - ohne Fehlermeldung :cry:

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Delete mit SQLite3 - Database locked

Beitrag von mse »

Poelser hat geschrieben:Wenn ich vorweg einen "DM.Query.Close" ausführe bleibt der Fehler bestehen.
Und wenn du nach dem close transaction.active:= false setzt?
Das Komponenten Interface zu SQLite3 ist vor allem bezüglich Transaktionen etwas trickreich, ich weiss nicht, ob bei Lazarus schon alles funktioniert. Es hat auch bei MSEgui einige Zeit gedauert bis es reibungslos lief.

Edit: MSEgui tsqlite3connection hat options slo_transactions flag welches standardmässig ausgeschaltet ist um solchen Problemen vorzubeugen. tmsetransaction hat zusätzlich options tao_fake. Schau doch mal, ob es diese Optionen in Lazarus ebenfalls gibt.

Poelser
Beiträge: 55
Registriert: Do 6. Nov 2008, 14:16
OS, Lazarus, FPC: Windows Vista (L 1.0.6 FPC 2.6.0)
CPU-Target: Intel 32 Bit/Arm

Re: Delete mit SQLite3 - Database locked

Beitrag von Poelser »

mse hat geschrieben:
Poelser hat geschrieben:Wenn ich vorweg einen "DM.Query.Close" ausführe bleibt der Fehler bestehen.
Und wenn du nach dem close transaction.active:= false setzt?
Das Komponenten Interface zu SQLite3 ist vor allem bezüglich Transaktionen etwas trickreich, ich weiss nicht, ob bei Lazarus schon alles funktioniert. Es hat auch bei MSEgui einige Zeit gedauert bis es reibungslos lief.

Edit: MSEgui tsqlite3connection hat options slo_transactions flag welches standardmässig ausgeschaltet ist um solchen Problemen vorzubeugen. tmsetransaction hat zusätzlich options tao_fake. Schau doch mal, ob es diese Optionen in Lazarus ebenfalls gibt.
Das war wohl ein Volltreffer :mrgreen: Ich hatte an einer Programmstelle eine verschachtelte QueryOuter/QueryInner. Dies funktioniert nur, wenn die Queries getrennte DB-Connections benutzen. Nach dem Füllen einer Datenstruktur mit diesen Daten habe ich nun ein DM.Con2.Transaction.Active := False nachgeschoben, und nun ist alles OK :D

CU, der Poelser

Antworten