Design SQL lock umgehen

Alles rund um die Programmierung mit Qt
Antworten
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Design SQL lock umgehen

Beitrag von AuE »

Hi,

bin grade am überlegen wie ich am Besten eine Sql lib realisiere.

Folgendes Problem: die DB soll sowohl schreibend als auch lesen auf eine SQLite DB. Das schreiben wird von einer TCP Verbindung aus getriggert. Das lesen von meinen Hauptprpgramm.

Dabei (also unter Stress) kann es passieren das die DB gelockt ist. Also zB nicht gelesen werden kann.

Meine Idee: Ich lasse alle read/write Befehle über Signale gehen => Sprich es kommt ein Lesebefehl => Signal welches dann getriggert wird. Schreiben => Signal.

Was erhoffe ich mir dadurch? Ich hoffe das ich so das lock der DB umgehen kann da ja die Signale am Ende (nach abarbeiten der Quue) erst abgeklappert werden. Somit sollte ich das Problem umgehen können - oder was denkt ihr?

Habt ihr das ggf anders gelöst? Wichit gist das es keine Server/Client DB ist - also die Lese/Schreibzugriffe von mir geregelt werden müssen.

Gruß u Dank!
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Ich bin jetzt mit SQLite nicht vertraut, aber warum sollte die DB einen Read-Lock haben?
Und wenn du es eh selbst wieder ausliest, warum verwendest du dann keine QQueue?
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Aus der SQLite FAQ
We are aware of no other embedded SQL database engine that supports as much concurrency as SQLite. SQLite allows multiple processes to have the database file open at once, and for multiple processes to read the database at once. When any process wants to write, it must lock the entire database file for the duration of its update. But that normally only takes a few milliseconds.
Das bedeutet das in dieser Zeit(beim schreiben) kein query Möglich ist! Ich denke das die Wahrscheinlichkeit das dies Auftritt gering ist - aber wenn ich es jetzt schon weiß kann ich ja versuchen das zu umgehen indem in den Writer via Signale ansteuere...Der kann ja dann eintragen am Ende der E-Loop. Somit wären dann schon alle vorhergehenden queries(read) durch!
Oder?
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

AuE hat geschrieben:Aus der SQLite FAQ
We are aware of no other embedded SQL database engine that supports as much concurrency as SQLite. SQLite allows multiple processes to have the database file open at once, and for multiple processes to read the database at once. When any process wants to write, it must lock the entire database file for the duration of its update. But that normally only takes a few milliseconds.
Das bedeutet das in dieser Zeit(beim schreiben) kein query Möglich ist! Ich denke das die Wahrscheinlichkeit das dies Auftritt gering ist - aber wenn ich es jetzt schon weiß kann ich ja versuchen das zu umgehen indem in den Writer via Signale ansteuere...Der kann ja dann eintragen am Ende der E-Loop. Somit wären dann schon alle vorhergehenden queries(read) durch!
Oder?
Ich hab deinen Ausgangspunkt oben nicht ganz verstanden. Hast du mehrere Prozesse die sowohl lesend als auch schreibend auf die DB zugreifen, oder wie?

Wenn ja, wo liegt dann das Problem? Das Lock hast du immer, wenn jemand schreibt, vollkommen unabhängig vom Rest der Welt. Das ist nach dem Schreibzugriff aber auch wieder weg. Normalerweise sollte eine Lese-Abfrage so lange blocken, bis das Lock weg ist. Ist das bei dir anders?
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Bei mehreren Prozessen kannst du schnell dazu komen das es zu locks kommt.

Die Datenbank ist quasi eine komfortablere LogDatei, dadurch kann es sein das sie viele Daten bekommt und der User aber auch gleichtzeitig was sehen will...
Daher muss ich das irgenwie umgehen!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Sehe ich das richtig dass du bisher noch kein Problem damit hattest, und nur auf Verdacht schon im Voraus optimieren willst?
Das locken macht SQLIte selber. Der lock verhindert nur dass gleichzeitig geschrieben und gelesen wird (wie eben bei Threads der ReadWriteLock). Das bedeutet aber nicht, dass du nicht gleichzeitig Queries schicken kannst. Solange kein Schreibender Prozess die Datenbank locked, sollten die Lesenden Queries parallel ausgeführt werden (wenn ich den Quote richtig deute). Sobald einer schreibt, wird gelocked, andere Queries werden gequeued, und sobald der Lock wieder frei gegeben ist, werden diese abgearbeitet. Der Lock heißt nämlich NICHT, dass die lesenden Queries geblockt und abgewiesen werden. Du wirst, wenn du das mit Qt::QueuedConnections machen willst, sogar eher Probleme haben, dass der User lange warten muss. Du baust ja da zusätzlich zu dem vorhandenen Lock-Mechanismus eine weitere Barriere ein.
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

So.... jetzt hab ich das Problem ;-)

Habe mir ein Testprogramm geschrieben, alle 100ms ein Query das einen Datensatz(die Zeit die ich mir von nen Server hole) einträgt und eine view die die sich eigentlich.... sobald ich ein query auf die vie abschieße is die Datenbank dicht:
New Data arrived "10:33:35.191"
Error performing query QSqlError(5, "Unable to execute statement", "database is locked")
28
New Data arrived "10:33:40.290"
Error performing query QSqlError(5, "Unable to execute statement", "database is locked")
28
New Data arrived "10:33:45.389"
Error performing query QSqlError(5, "Unable to execute statement", "database is locked")
28
New Data arrived "10:33:50.489"
Das Programm ist dann komplett dich es geht nix mehr!


EDIT: Fehler gefunden ;)

Wenn ich mit dem SQLLite Database Browser auf der DB hänge und dort eine query absende.... gibt dieser so lange die DB nicht wieder frei bis man auf "save" klickt ;)
Antworten