Servus, folgendes Problem: Ich entwickle eine Archivsoftware unter SQLite + Web, das System ist aktiv und läuft. Sporadisch (ca. 20 mal in den letzten 2 Jahren) tritt ein merkwüdiges Problem auf: Ich habe mehrfach vergebene rowids, die Daten nur des letzten Records sind in der db. Programmausschnitt: erstes db-Handle: offene Zieedatebank, attached ist eine weitere db mit Daten. Die Dateen sollen von de zweiten in die erste transferiert werden (es sind unterschiedliche db-files). begin immediate insert into archiv eetcpp. return value == 0 -> alles ok, löschen in der ersten und end transaction return value != 0 -> rollback; und Ende Im Fehlerfall erscheint bei bis zu 5 aufeinandelfolgenden inserts die gleiche rowid - darf ja eigentlich nicht seein. Alle returns von SQLite sind 0 und versuchen mir zu sagen, alles sei ok. Während der transaction aktualisiere ich noch eine andere Datenbank über eine andere connection. Gefunden habe ich das auf der Suche nach fehlenden Belegen. Protokolliert ist der Vorgang auch (Ausschnitt): ---------------------- Barcode 60000000078034 Ablagedatum (BELEG_DATUM = 15.05.2015) 15.05.2015, Ablagejahr 2015 execute ARCHIV: 'attach 'E:\++++\AKTUELL\ruk\temp\archiv.sdb' as 'tempdb'' 0.0000 sec, 1 Versuch(e) Standard-Barcode E:\++++\AKTUELL\ruk\temp\03379876.pdf Schreibe PDF : E:\++++\AKTUELL\ruk\temp\03379876.pdf -> E:\ACCON\AKTUELL\ruk\2015\archiv_0515.t, 4960708 Bytes at $073afb4c execute ARCHIV: 'begin immediate' 0.0000 sec, 1 Versuch(e) Aktualisiere History für '60000000078034', Jahr 2015 execute HISTORY: 'update history set PRTFILE = 'usquery_impidx_20170303-08001014.prt, usquery_impwf_20170307-12001024.prt', LOCATION = 'ruk/2015', ARCDAT = '2017-03-07', STATUS = 'archiviert' where BARCODE_NR = '60000000078034'' 0.0000 sec, 1 Versuch(e) SQLAppend INSERT INTO ARCHIV (FPOS,BARCODE_NR,BELEG_DATUM,BELEG_KZ,BELEG_NR,BELEG_NUMMER,BEL_ART,BETR AG_1,BETRAG_2,BETRAG_3,BETRAG_4,BRUTTO,BUCHUNG_DATUM,KOMMENTAR,LOESCH_KZ ,NETTO,REGULIERUNGS_KZ,SAP_BU_KREIS_R3,SAP_MA_NR_R3,SCANDATUM_R3,URSP_KZ ,VL_NR,VORGANGS_ID,VORGANGS_NR,WAEHRUNG,WAWI_NR,REISENDER,WF_Import,SaKo nto,KOSTSTELL,SCANDATE,LOGFILE,IDXNR) VALUES ('0515 73afb4c','60000000078034','2015-05-15','R','','69007827','00100032','000 000000','000000000','000000000','000000000','226,86','2015-05-15','MS HAMBURG HAM1515','X','226,86','0','0008','60','','0000000000','2008','0000000000 0000000000','00000000000000','EUR','00000','','03.03.2017','445030','',' ','','03379876'), result 0 rowid 383721 Lösche aus temp: delete from tempdb.archiv where BARCODE_NR = '60000000078034' = 0 end transaction = 0 detach temp = 0 ok -> archiviert --------------- Der Beleg ist dann weg. Der nächste hat die gleiche rowid ... Vielleicht hat jemand eine Idee (im Web habe ich nur gefunden daß SQLite das alles kann). Die Änderung in HISTORY sind vorhanden, die anderen nicht.
Joachim D. schrieb: > Ich habe mehrfach vergebene rowids, die Daten nur des letzten Records > sind in der db. Das hört sich so an, als ob die vorherigen Daten nicht wirklich geschrieben wurden. Benutzt du Netzwerk-Dateisystem oder virtuelle Maschinen (siehe http://www.sqlite.org/howtocorrupt.html)?
Hi Clemens, läuft unter Apache auf Win7. Die Daten werden nicht geschrieben, es ist immer nur der letzte mit der rowid x in der db.
Gibt es ein Unique-Constraint auf dem Attribut? Sorry, vergiss es, hab an etwas anderes gedacht....
:
Bearbeitet durch User
Clemens L. schrieb: > Das könnte ein Fehler in deinem Code sein ... Schön wär's ;) Ich habe das einige Male pingelig kontrolliert, ich befürchte Nein. Im Moment bin ich schlicht ratlos. Es passiert ja auch ziemlich selten ... Nach dem Datenimport (jeweils ein PDF und Indexdaten) läuft ein Prüfprogramm was zu jeder rowid prüft ob die Sachen da sind. Das hat dann natürlich keinen Fehler gefunden. Vor ein Paar Wochen habe ich die Prüfung af rowid und Barcode_Nr erweitert und bin so auf den Effekt gekommen.
>ein merkwüdiges Problem auf: Ich habe mehrfach vergebene rowids lass mich raten wie das Abläuft 1. gibts die rowid schon? -> nein -> Insert <- das ist der Fehler in deiner Erkennung 2. Update rowid-Satz auf neue Daten -> alter Satz wird auch überschrieben https://www.techonthenet.com/sqlite/unique.php sowas ohne Constraint zu machen ist wie Autofahren ohne Gurt - er ist da - es wird dadurch sicherer - vermeidet Unfälle - NUTZE DEN GURT mit einem Unique Constraint kannst du die doppelte rowid gar nicht ohne das SQLite einen Fehler meldet mit Insert in deine Datenbank bekommen - dein händisches Prüfen ist definitiv falsch - es kann nicht anders passieren
Moin Bert, die rowid wird von SQLite vergeben. Ich habe da keinen Einfluß drauf. Nach dem insert hole ich mir die von SQLite per sqkite3_last_insert_rowid() ab.
Poste doch erst mal dein Datenbankschema (.schema), am besten als Anhang.
Joachim D. schrieb: > Ich entwickle eine Archivsoftware unter SQLite + Web, das System ist > aktiv und läuft. SQLite ist nur dann thread-safe, wenn man es a) entsprechend übersetzt und b) den Multithreading- oder Serialized-Modus einschaltet. Warum benutzt Du nicht eine richtige Datenbank wie PostgreSQL?
Joachim D. schrieb: > Clemens L. schrieb: >> Das könnte ein Fehler in deinem Code sein ... > > Schön wär's ;) > > Ich habe das einige Male pingelig kontrolliert, ich befürchte Nein. Und woher soll ich wissen, ob du die hypothetischen Fehler erkennen kannst? (Und wenn du dazu in der Lage wärst, warum fragst du dann hier?)
Clemens L. schrieb: > warum fragst du dann hier? Um eine Entscheidungshilfe zu suchen. Ich weiß nicht ob ich da Mist gebaut habe oder es ein Problem von SQLite ist. Eigentlich ist es bei SQL ja nicht üblich, eine Transaktion mit "alles ok" zu beenden und dann eine Nase zu drehen ;)
>die rowid wird von SQLite vergeben. Ich habe da keinen Einfluß drauf. >Nach dem insert hole ich mir die von SQLite per >sqkite3_last_insert_rowid() ab. hast du mehrere Threads welche die selbe connection nutzen - oder kann dein "Web" das verursachen? würde aber nur dazu führen können das du z.B. eine falsche rowid bekommst und laut: https://www.sqlite.org/autoinc.html >In SQLite, table rows normally have a 64-bit signed integer ROWID which is >unique among all rows in the same table. (WITHOUT ROWID tables are the >exception.) sollte es gar nicht möglich sein das du doppelte rowids im Table hast ausser hier: https://www.sqlite.org/c3ref/last_insert_rowid.html >If a separate thread performs a new INSERT on the same database connection >while the sqlite3_last_insert_rowid() function is running and thus changes >the last insert rowid, then the value returned by >sqlite3_last_insert_rowid() is unpredictable and might not equal either >the >old or the new last insert rowid. und darüber der text bezüglich "funktioniert" und nicht funktioniert ist auch ein wenig schwierig imer Internt habe ich noch diesen Tip gefunden > begin; > insert into tbl( filed ) VALUES ( 1 ); > Select last_insert_rowid() as li; > commit;
Joachim D. schrieb: > Ich weiß nicht ob ich da Mist gebaut habe oder es ein Problem von > SQLite ist. Dass es ein Bug in SQLite ist, ist extrem unwahrscheinlich. Dass du ein Dateisystem/OS/Hardware benutzt, das die Daten einfach wegschmeißt, hast du oben ausgeschlossen. Also bleiben nur Fehler im Zusammenhang mit Threading, oder irgendwelche anderen Programmierfehler.
> Dass es ein Bug in SQLite ist, ist extrem unwahrscheinlich. Äh ... klar. Ich glaube das ja auch nicht (und weiß es nicht). > Dass du ein Dateisystem/OS/Hardware benutzt, das die Daten einfach > wegschmeißt, hast du oben ausgeschlossen. Also bleiben nur Fehler im > Zusammenhang mit Threading, oder irgendwelche anderen Programmierfehler. Oder nicht so verwendet wie sich SQLite das gedacht hat. Das Problem ist, ich kann es nicht bewußt herbeiführen - dazu passiert es zu selten. Aktuell wurde knapp 400.000 Belege so bearbeitet, 2 mal hat es gezickt. Ich könnte mir vorstellen, daß SQLite vielleicht ein Problem mit der transaction und der in einer anderen connection geöffneten Datenbank hat. Vielleicht bezieht sich die transaction nur genau auf die aktuelle connnectioon (das Web sagt, es gehe). Wenn ich da irgendwo Mist gebaut habe, kann ich das wenigstens abstellen ;)
Joachim D. schrieb: > Ich könnte mir vorstellen, daß SQLite vielleicht ein Problem mit der > transaction und der in einer anderen connection geöffneten Datenbank > hat. Vielleicht bezieht sich die transaction nur genau auf die > aktuelle connnectioon (das Web sagt, es gehe). Zwischen Connections und Transaktionen ist eine 1:1-Beziehung. Mit Transaktionen kannst du verschieden Connections voneinander isolieren. Aber ich habe keine Ahnung, ob dein Code Transaktionen korrekt benutzt.
Clemens L. schrieb: > Zwischen Connections und Transaktionen ist eine 1:1-Beziehung. Mit > Transaktionen kannst du verschieden Connections voneinander isolieren. Bedeutet ? Ich habe in einer trasnsaction 2 aktive connections. Das sollte eigentlich ok sein und funktionieren ...
Eine Connection erhältst du mit sqlite3_open(). Ein ATTACH erzeugt keine neue Connection.
Clemens L. schrieb: > Eine Connection erhältst du mit sqlite3_open(). Ein ATTACH erzeugt keine > neue Connection. Klar.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.