Datenbank bei jedem Zugriff öffnen und schließen oder nur einmal öffnen
-
Wenn alle 30 Sekunden ein Zugriff erfolgt würde ich die Datenbank offen lassen.
Das Problem sehe ich an sich schon in der Verwendung einer Access Datenbank.Für diese Client Menge ist das Ding wirklich nicht gebaut. Bei einer gleichmässigen Verteilung hast Du wenigstens 3 Updates pro Sekunde mit sicherlich nicht geringen Wachstum der Datenbank.
Ich würde Dir von einer AccessDB abraten. Wenn jetzt noch lesende Clients dazukommen wird das zur keimenden Kartoffel.
-
Ich glaube, dass ich mir seitdem eher mal die DB sperre, also Parallelabfragen (oder was auch immer, da suche ich noch) nicht mehr möglich sind.
Ich hoffe, ich denke dran, wenn ich den Fehler mal wieder habe, dann werde ich es mal testen.
-
Martin Richter schrieb:
Wenn alle 30 Sekunden ein Zugriff erfolgt würde ich die Datenbank offen lassen.
Das Problem sehe ich an sich schon in der Verwendung einer Access Datenbank.Für diese Client Menge ist das Ding wirklich nicht gebaut. Bei einer gleichmässigen Verteilung hast Du wenigstens 3 Updates pro Sekunde mit sicherlich nicht geringen Wachstum der Datenbank.
Ich würde Dir von einer AccessDB abraten. Wenn jetzt noch lesende Clients dazukommen wird das zur keimenden Kartoffel.
Aloha Martin,
nee, haste Dich verlesen. Nur der Server greift auf die DB !!!
Und das passiert dann tatsächlich ca. bis zu 300 x die Minute, das aber auch nur in Spitzenzeiten.Vorteil der Access DB ist, dank der Jet Engine läuft sie nun in einer Umgebung, auf die ich nicht wirklich Zugriff habe und wo auch kein Access installiert ist.
Meine Frage ist nach wie vor, ist es ungewöhnlich die DB die komplette Laufzeit offen zu lassen ?
Grüße und Danke
BOA
-
estartu schrieb:
Ich glaube, dass ich mir seitdem eher mal die DB sperre, also Parallelabfragen (oder was auch immer, da suche ich noch) nicht mehr möglich sind.
Ich hoffe, ich denke dran, wenn ich den Fehler mal wieder habe, dann werde ich es mal testen.
Aloha,
genau das scheint mein Porblem ich bekomme ne Meldung
Das Microsoft Jet-Datenbankmodul hat den Vorgang angehalten, da Sie und ein weiterer Benutzer gleichzeitig versuchen, dieselben Daten zu verändern.
Grüße
BOA
-
Hast du nun eigentlich nur den Server, der nur ein Recordset hat und damit schreibt er?

Wenn das der Fall ist, dürftest du ja gar keine Parallelzugriffe haben.Oder wie ist das gelöst? Wann wird geschrieben?
-
estartu schrieb:
Hast du nun eigentlich nur den Server, der nur ein Recordset hat und damit schreibt er?

Wenn das der Fall ist, dürftest du ja gar keine Parallelzugriffe haben.Oder wie ist das gelöst? Wann wird geschrieben?
Aloha,
nein, wenn der Client eine Message schickt, öffnet der Server eine Tabelle und filtert nach der Client - ID einen bestimmten Datensatz der Tabelle raus ändert diesen, macht ein Update und schließt die Tabelle danach wieder.
Dann könnte die nächste Message abgearbeitet werden...
Grüße
BOA
-
Kann es also vorkommen, dass der zwei gleichzeitig schreiben will?
Mach zur Not mal ein TRACE an den Anfang der Funktion und eins ans Ende, dann siehst du ob es daran liegt.
-
Also wenn nur der Server das Dingbraucht. Würde ich den gesamten Datenbankzugriff in einem Thread über eine Queue synchronisieren. Es würde sowieso synchronisiert werden, dann aber über die DB und das ist weitaus uneffektiver, als wenn Du alles in einer Queue sammelst und diese Queue von einem Thread abgearbeitet wird, der die ganze Zeit die DB natürlich offen hat.
-
Martin Richter schrieb:
Also wenn nur der Server das Dingbraucht. Würde ich den gesamten Datenbankzugriff in einem Thread über eine Queue synchronisieren. Es würde sowieso synchronisiert werden, dann aber über die DB und das ist weitaus uneffektiver, als wenn Du alles in einer Queue sammelst und diese Queue von einem Thread abgearbeitet wird, der die ganze Zeit die DB natürlich offen hat.
Aloha,
das ist gar keine schlechte Idee, danke für den Tip, werde ich mal andenken, ob ich das schnell umschreibe...
Und wie ich lese, ist es also auch nicht ungewöhnlich, dass die DB offen bleibt...
Danke und Grüße
-
estartu schrieb:
Kann es also vorkommen, dass der zwei gleichzeitig schreiben will?
Mach zur Not mal ein TRACE an den Anfang der Funktion und eins ans Ende, dann siehst du ob es daran liegt.Eigentlich sollte es nicht vorkommen, da nur alle 30 sekunden von einem Client eine Message geschickt wird. Soll heißen dergleiche Datensatz wird nur alle 30 Sekunden angefaßt....
Ich habe etwas gelesen, dass diese Fehlermeldung bei Access auch vorkommen kann, wenn die DB irgenwie beschädigt wurde. Man soll dann einfach alle Tabellen kopieren und in eine leere reinpacken.
Kennt sich damit jemand aus, geht das mit allen Tabellen auf einmal, oder nur einzeln ?
Grüße und Danke
BOA
-
BOA schrieb:
estartu schrieb:
Kann es also vorkommen, dass der zwei gleichzeitig schreiben will?
Mach zur Not mal ein TRACE an den Anfang der Funktion und eins ans Ende, dann siehst du ob es daran liegt.Eigentlich sollte es nicht vorkommen, da nur alle 30 sekunden von einem Client eine Message geschickt wird. Soll heißen dergleiche Datensatz wird nur alle 30 Sekunden angefaßt....
Kann es sein, dass die Meldung
Das Microsoft Jet-Datenbankmodul hat den Vorgang angehalten, da Sie und ein weiterer Benutzer gleichzeitig versuchen, dieselben Daten zu verändern.
heißt, dass du zweimal auf die gleiche Tabelle zugreifen willst?
Das dachte ich bisher immer, aber von Jet habe ich keine Ahnung.
Und das wäre nicht alle 30 Sekunden, sondern eben bis zu 100 mal öfter.

-
Aloha,
das ist eine gute Frage, ich hätte wie gesagt auf den Datensatz getippt.
Ich muß das mal eruieren....Aber ich denke, dass mit der DB auch etwas nicht stimmt, da in einzelnen Tabellen Werte geändert werden, ohne das ein Zugriff vom Server Proggi erfolgt...

Das ist schon spannend...
Grüße und Danke
BOA
-
Hi,
das hat tatsächlich geholfen, eine neue DB anzulegen und die Tabellen hineinzukopieren.
Ich bekomme keine Fehlermeldungen mehr und auch ominöse Änderungen finden nicht mehr statt in den Tabellen...
Erstaunlich....
Grüße
BOA
-
Wenn du kannst dann nimm den MSSQL 2005 Express. Ist wesentlich robuster und auch schön gratis. Einzig die Limitierung auf 2GB (oder waren es 4GB?) könnte u.U. lästig werden...
-
MSDE 2000 war auf 2GB limitiert
SQL 2005 Express auf 4GB
-
Martin Richter schrieb:
Also wenn nur der Server das Dingbraucht. Würde ich den gesamten Datenbankzugriff in einem Thread über eine Queue synchronisieren. Es würde sowieso synchronisiert werden, dann aber über die DB und das ist weitaus uneffektiver, als wenn Du alles in einer Queue sammelst und diese Queue von einem Thread abgearbeitet wird, der die ganze Zeit die DB natürlich offen hat.
Hi Martin,
zu dieser Queue Geschichte habe ich noch ne Frage.
Ich habe mir nun ne <list> m_listeMessagesangelegt und lasse per Timer jede Sekunde diese in folgender Manier durchlaufen :for(list<mes>::iterator itMes = m_listeMessages.begin(); itMes != m_listeMessages.end(); itMes++) { MessageReceive(itMes->message, itMes->sock); itMes = m_listeMessages.erase(itMes); itMes--; }Wie reagiert das Programm eigentlich ? Ich arbeite nun z.B. 7 Nachrichten in der Schleife ab, in der zwischenzeit loggt sich ein neuer User ein. Wird die Schleife erst abgearbeitet oder wird die neue Message gleich in die Liste gepackt ?

Hättest Du Deine Queue ähnlich gebastelt ?

Danke und Grüße
BOA
-
Wenn Du das so machst und ein anderer Thread fügt was in die Liste ein, dann wird es nicht lange dauern und Dein Listenobjekt ist zerstört.
Du musst in jedem Fall das Objekt blockieren durch eine Critical Section.
Und warum die Schleife durchlaufen?
CCriticalSection m_critical; list<mes> m_listeMessages; ... while (bProgramIsNotTerminated) { mes m; bool bDoit = false; { CSingleLock lock(&m_critical,TRUE); // Something to work if (m_listeMessages.size()) { m = m_listeMessages.front(); m_listeMessages.pop_front(); bDoit = true; } } if (bDoit) MessageReceive(m.message, m.sock); }So kann auch während MessageReceive ausgeführt wird etwas in die Liste gepackt werden.
Wichtig ist das beim einfügen auch die Criticalsection verwendet wird.
mes m; if (GetNextMes(m)) { CSingleLock lock(&m_critical,TRUE); m_listeMessages.push_back(m); }
-
Martin Richter schrieb:
Wenn Du das so machst und ein anderer Thread fügt was in die Liste ein, dann wird es nicht lange dauern und Dein Listenobjekt ist zerstört.
Du musst in jedem Fall das Objekt blockieren durch eine Critical Section.
Und warum die Schleife durchlaufen?
CCriticalSection m_critical; list<mes> m_listeMessages; ... while (bProgramIsNotTerminated) { mes m; bool bDoit = false; { CSingleLock lock(&m_critical,TRUE); // Something to work if (m_listeMessages.size()) { m = m_listeMessages.front(); m_listeMessages.pop_front(); bDoit = true; } } if (bDoit) MessageReceive(m.message, m.sock); }So kann auch während MessageReceive ausgeführt wird etwas in die Liste gepackt werden.
Wichtig ist das beim einfügen auch die Criticalsection verwendet wird.
mes m; if (GetNextMes(m)) { CSingleLock lock(&m_critical,TRUE); m_listeMessages.push_back(m); }Hallo,
vielen Dank für die schnelle Antwort.
Diese Technik ist mir neu, speziell das mit dem CSingleLock und CCriticalSection.Ich werde das einmal probieren umzusetzen und werde dann berichten, solange vielen Dank erstmal.
Beste Grüße
BOA
-
Wenn Du mehrere Threads benutzt, dann ist das Pflicht!
-
Martin Richter schrieb:
Wenn Du mehrere Threads benutzt, dann ist das Pflicht!
Hi,
ja ich benutze mehrere Threads, und hatte auch ab und zu einen undefinierten Absturz der exe mit einer Speicherzugriffsverletzung...
Ich teste mal, vielen Dank.
Beste Grüße
BOA