in threads auf event warten und Datenbank Zugriff parallel
-
Hallo zusammen,
(Borland C++ Builder 5.0 / IBOS )
Ich möchte gerne auf einen Event warten und dann in einem Thread auf eine Datenbank zugreifen und Daten um kopieren.
D.h. Bis jetzt warte ich auf ein Event in der "Hauptanwendung" wenn ich es bekomme starte ich ein thread, der in eine Datenbank schaut und dann Dateien umkopiert, danach werden nochmal Einträge in die Datenbank gemacht.
Das funktioniert so lange ich kein zweites Event bekomme.
Wenn das geschieht, „verschluckt sich die Anwendung“ ich bin mir nicht sicher ob der Thread nicht richtig weiter läuft, es Konflikte mit den Komponenten gibt ? (mehrere Datenbank – zugriffe ??) .
Also
Erst wird nach dem Event(in der "Hauptanwendung") ein thread gestartet:
if(AEventName == "GO") { if(!db_BASIS->Connected) db_BASIS->Connected = true; Application->Restore(); THR_BILDER = new thrBILDER(true); THR_BILDER->Priority = tpHigher; THR_BILDER->FreeOnTerminate = true; THR_BILDER->Resume(); Application->Minimize(); }in dem Thread wird geschaut wieviele dateien von wo nach wo umkopiert werden :
asSQL = "select id,pfad_von,pfad_nach from t_bild"; try { qry_Read3->SQL->Clear(); qry_Read3->SQL->Add(asSQL); qry_Read3->Prepare(); qry_Read3->Open(); qry_Read3->First(); while(!qry_Read3->Eof) { asPfad_Von = qry_Read3->FieldByName("pfad_Von")->AsString; asPfad_Nach = qry_Read3->FieldByName("pfad_Nach")->AsString; if(asPfad_Von != "") { if(FileExists(asPfad_Von.c_str())) { asDirectory = ExtractFileDir(asPfad_Nach); if(ForceDirectories(asDirectory)) { if(!MoveFileEx(asPfad_Von.c_str(),asPfad_Nach.c_str(),MOVEFILE_REPLACE_EXISTING)) { Protokol("File(nicht kopieren) " + asPfad_Von + " konnte nicht nach" + asPfad_Nach + " verschoben werden",asDATUMUHRZEIT); if(!CopyFile(asPfad_Von.c_str(),asPfad_Nach.c_str(),false)) { iStatus = 99; } else { DeleteFile(asPfad_Von.c_str()); } } } else { Protokol("Directory " + asDirectory + " konnte nicht erzeugt werden",asDATUMUHRZEIT); iStatus = 99; } } else { Protokol("File " + asPfad_Von + " existiert nicht",asDATUMUHRZEIT); iStatus = 99; } if(iStatus == 99) iStatus_Auftrag = 999; asSQL = "update t_bild set status = " + IntToStr(iStatus); asSQL += " where id = "+ qry_Read3->FieldByName("id")->AsString; SetData(asSQL); }// if(asPfad_Von != "") qry_Read3->Next(); } qry_Read3->SQL->Clear(); qry_Read3->Close(); qry_Read3->Unprepare(); } catch(...) { qry_Read3->SQL->Clear(); qry_Read3->Close(); qry_Read3->Unprepare(); }Das funktioniert auch wenn nur ein Thread läuft.
(wenn er hier in der while schleife ist und das Hauptprogramm bekommt ein Event und startet einene weiteren Thread, dann werden die weiteren Einträge nicht berücksichtigt, die Dateien werden nicht mehr umkopiert.)
Ich denke habe irgendwie das gefühl das der Thread aus der Schleife
"while(!qry_Read3->Eof)"
gerissen wird.
"kann das sein ? kann das wo anders drann liegen ? Hat einer irgend eine Idee ???
Über hilfe würde ich mich sehr freuen

P.S. Der zweite Thread läuft dann sauber durch nur der erste nicht.
Danke
YLIREBUS
/Edit : String-Literal im Quellcode korrigiert
-
Hi, vielleicht so etwas (Pseudocode):
if(event_nr_2) { while(alter_thread_noch_aktiv) ; // ah, jetzt ist er zuende, also: neuen_thread_erstellen(event_nr_2); }Warte erstmal ab, bis der alte Thread fertig durchgelaufen ist und starte dann den neuen. Oder häufen sich dann auf Dauer zuviele Warteschleifen an?
Gruß,
Christian
-
Erstellst Du in jedem Thread eine neue Verbindung / Transaktion? Was für eine Isolationsstufe verwendest Du?
Grüße Joe_M.
-
@Christian Sonder
Die threads sollten schon parallel arbeiten nicht hintereinander ;-).@zufaulzumeinloggen
Ja, ich erstelle in jedem thread eine neue Verbindung / Transaktion.--> Was für eine Isolationsstufe verwendest Du?
Hier weiss ich leider nicht wovon Du sprichst ;-(. (tut mir leid)Meinst Du so etwas wie :
TCriticalSection ?
(Habe schon versucht mit "CriticalSection" zu arbeiten , bin mir nur nicht sicher an welcher Stelle sie wirklich nötig sind.)
Habe im Entwicklerhandbuch eine Stelle gefunden, die noch von den Interbase Komponenten spricht und diese ausdrücklich als "Threadsicher" beschreibt.
(Ich gehe mal davon auß, das die IBO's das auch sind, die kamen ja erst später raus ;-))Von daher habe ich bei allem was Datenbankzugriff angeht "CriticalSection" weg gelassen.
(Habe aber vorher auch schon den Test gemacht und um jeden Zugriff eine
"CriticalSection" gebaut - ohne Erfolg ;-(.Wenn Du was anderes meinst, bitte ich um Aufklärung

Danke Euch erstmal
Ylirebus
-
Hallo, nein eine TCriticalSection benötigst Du hier nicht. Zumindest fällt mir keine Stelle auf.
Mit Isolationsstufe meine ich die Isolationsstufe der Transaktionen. Diese würde ich auf tiConsistency setzen (bei TIBO_Transaction::Isolation). Das ist die 'höchste Sicherheitsstufe', die Datensätze in einer gestarteten Transaktion werden gesperrt und andere Transaktionen können diese nicht modifizieren. Ich vermute, die Transaktionen kommen sich gegenseitig ins Gehege.
Und wie gesagt, Du benötigst für jeden Thread eine komplett neue Verbindung zur Datenbank. Du darfts kein gemeinsames TDataModule verwenden, es sei denn, Du erzeugst in jedem Thread eine neue Instanz.
Grüße Joe
-
Danke Dir erst einmal für Deine Mühe Joe_M.
Ich habe Deinen Rat befolgt und die Isolation auf "tiConsistency"
gesetzt.Leider ist das Ergebnis unverändert ;-(.

Ich suche weiter

-
Es geht aber wohl in die Richtung habe mal das mitgelieferte Errorprotokol aktiviert :
26.03.2007 15:07:39 - ErrorMessage: ISC Fehlernummer:335544345 26.03.2007 15:07:39 - ErrorMessage: 26.03.2007 15:07:39 - ErrorMessage: ISC Fehlermeldung: 26.03.2007 15:07:39 - ErrorMessage: lock conflict on no wait transaction 26.03.2007 15:07:39 - ErrorMessage: STATEMENT: TIB_Query: "<TApplication>.dm.qry_Write." 26.03.2007 15:07:39 - ErrorCodes: 335544345 26.03.2007 15:07:39 - ErrorCodes: 0 26.03.2007 15:07:39 - SQLMessage: SQL Fehlernummer:-901 26.03.2007 15:07:39 - SQLMessage: 26.03.2007 15:07:39 - SQLMessage: SQL Fehlermeldung: 26.03.2007 15:07:39 - SQLMessage: Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements 26.03.2007 15:07:39 - ErrorMessage: ISC Fehlernummer:335544345 26.03.2007 15:07:39 - ErrorMessage: 26.03.2007 15:07:39 - ErrorMessage: ISC Fehlermeldung: 26.03.2007 15:07:39 - ErrorMessage: lock conflict on no wait transaction 26.03.2007 15:07:39 - ErrorMessage: