Datenbanksynchronisierung bei Programmstart und -ende

  • VB.NET

Es gibt 49 Antworten in diesem Thema. Der letzte Beitrag () ist von MaThoPa1973.

    Datenbanksynchronisierung bei Programmstart und -ende

    Hallo Zusammen,
    aus lauter Verzweiflung, weil ich nicht mehr weiter weiß, habe ich mich, in der Hoffnung, dass Ihr mir weiterhelfen könnt´, hier angemeldet. Zudem hoffe ich, dass ich meine Frage in der richtigen Rubrik eingestellt habe. Also, folgendes Problem stellt sich mir gerade...

    Ich stecke gerade in der Neuentwicklung eines Programms (mit Visual Studio 2010) welches eine Access-Datenbank beinhaltet. Neuentwicklung daher, weil ich das Programm bereits mit VB6 geschrieben habe - jedoch ohne Netzwerkunterstützung (also rein lokale Installation und Nutzung).
    Da das Programm auf mehreren Rechnern gleichzeitig zur Anwendung kommen wird, ist in jeder lokalen Installation diese Access-Datenbank (beinhaltet 2 Tabellen) abgelegt.
    Zusätzlich wird aber auch diese Datenbank auf einem Netzwerklaufwerk abgelegt. Beim starten des Programmes wird geprüft, ob das Netzwerk verfügbar ist. Ist es verfügbar (und somit auch die auf dem Netzwerklaufwerk abgelegte Access-Datenbank), soll diese mit der lokalen Access-Datenbank abgeglichen werden. Selbiges soll auch durchgeführt werden, wenn das Programm beendet wird.
    Hintergrund ist der, dass das Programm seine volle Funktionalität auch in dem Fall eines Netzwerkausfalls behält. Zudem sollen die Daten, die nach der Synchronisation in die Zentraldatenbank (auf dem Netzwerklaufwerk) übertragen wurden, den anderen Usern auf den lokalen Arbeitsplätzen zur Verfügung stehen. Ist das Netzwerk, und somit die zenrtrale Datenbank, nicht verfügbar soll nur mit dem aktuellen Datenbestand der lokalen Datenbank gearbeitet werden - die erneute Synchronisation mit der Zentraldatenbank erfolgt dann erst wieder bei Programmstart (oder Ende).

    Ich hoffe Ihr konntet meinen Ausführungen und dem von mir verfolgten Ziel soweit folgen. Und nochmehr hoffe ich natürlich, dass da draußen in den Weiten des WWW irgendwo ein schlauer Kopf ist, der mir bei meinem Problem helfen kann... mein Kopf ist scheinbar nicht schlau genug

    Vielen Dank an alle die mir "auf die Sprünge" helfen.

    Gruß aus dem schönen Hunsrück
    Markus
    Wie willst du das Parallelitäts-Problem lösen?

    Also 2 User synchronisieren und laden die DB, und öffnen beide den Datensatz#2.

    User1 macht ein paar Änderungen, speichert ab und re-synchronisiert.

    User2 macht ein paar Änderungen, speichert ab und re-synchronisiert ebenfalls.

    Ätsch! die Änderungen von User2 überschreiben die Änderungen von User1, und der wird schön fluchen.

    Frage ans Konzept: wie ist das gelöst / wie willstedas lösen?
    Das Parallelitätsproblem in der Form wird es nicht geben!
    Grund: Die lokale Datenbank soll sich beim Starten des Programms mit der Datenbank auf dem Netzlaufwerk synchronisieren. Ein erneutes Synchroniseren erfolgt erst beim Beenden des Programms. Darüber hinaus wird es keine Bearbeitung von einem Datensatz an zwei Arbeitsplätzen geben - zumindest nicht innerhalb eines Tages. Somit sollte es das Probelem der Parallelität nicht geben.

    Tabelle 1 der Datenbanken dient rein der Kundenverwaltung, in Tabelle 2 erfolgt nur die einfache Speicherung von Werten. Auf Grund dessen das Kunde A entweder durch den Benutzer an Platz X aber nicht durch Benutzer an Platz Y bedient wird sollte es hinsichtlich der Parallelität keine Probleme geben.

    Mir ist auch soweit klar, dass die Synchronisierung Morgens (bei Programmstart) von der Datenbank auf dem Netzwerklaufwerk in Richtung Lokalplatz gehen muss, und Abens (bei Programmende) dann von dem Lokalplatz in Richtung Netzlaufwerk gehen muss. Abends werden quasi alle Aktualisierungen der Lokalplätze in der zentralen Datenbank gespeichert und am nächsten Morgen, bei Programmstart dann komplett an die loaklen Datenbanken übergeben werden damit man dann alle Daten zur Verfügung hat - egal ob am Tag zuvor Kunde A von Platz x bedient wurde und am nächsten Tag von Platz y aus bedient wird.

    Danke vielmals für die Unterstützung.
    Danke vielmals, aber leider hilft mir das bei meinem Problem nicht wirklich weiter. Es wäre zwar kein Problem das Synchro-Center bei mir für meine Zwecke einzurichten aber dann würde das Ganze noch nicht auf anderen Rechnern laufen - und schon garnicht, wenn auch noch unterschiedliche Betriebssysteme laufen.

    Ich habe mir nun folgenden Weg überlegt:
    1. In der lokalen Datenbank werden zusätzliche Tabellen angelegt (KundenNeu, KundenGeändert, KdWerteNeu, KdWerteGeändert).
    2. Wird ein neuer Kunde angelegt, dann wird der nicht nur in der lokalen Tabelle Kunden gespeichert sondern zusätzlich auch in der Tabelle KundenNeu. Wird ein Stammdatensatz geändert wird es in KundenGeändert gespeichert, usw. - soweit noch nachzuvollziehen?!
    3. Beim Programmstart wird geprüft ob die Tabellen ...Neu, bzw. ...Geändert Datensätze enhalten. Dies wird beim Programmstart gleichzeitig das Signal sein, dass beim vorangegangenen Programmende keine Synchronisierung stattgefunden hat (Upload zur Zentraldatenbank - was dann, insofern Netzwerk verfügbar ist, zuerst durchgeführt wird).
    4. Im Anschluß an ein Upload (auf die Zentral-DB) werden die lokalen Tabellen ...Neu, bzw. ...Geändert geleert.
    5. Für den Download (von der Zentral-DB) auf die lokalen Plätze brauchen dann nur die Tabellen Kunden und Werte abgeglichen, und neue Datensätze auf die lokale DB angefügt werden.

    Problem hierbei ist nur, dass ich bei den TableAdaptern von VB 2010 noch nicht so ganz durchsteige. Wenn alle Stricke reissen werde ich da über ADODB.Recordsets und mit Schleifen programmieren - dann wird das System zwar langsamer aber es sollte laufen.

    Oder kann mir einer eine gute Anleitung für die Prgrammierung von TableAdaptern zukommen lassen?

    Danke vielmals für Eure Unterstützung.



    Gruß
    Markus
    OK, Danke. Da werde ich mich dann mal umsehen in der Hoffnung fündig zu werden. Die TableAdapter sollen einem ja durchaus eine Menge Arbeit abnnehmen. Und wenn ich an die Schreibarbeit denke die bei ADO zusammen kommt ist man für jeden Tastendruck der weniger erforderlich ist, dankbar.
    Ich danke jedenfalls für den Hinweis - werde ich fündig dann werde ich hier natürlich auch für die Nachwelt die Lösung präsentieren - ansonsten werde ich mich hier einfach nochmal melden.

    Gruß
    Markus
    Was hältst du denn davon einfach in jeder Tabelle die Info über die "letzteBearbeitung" - sprich ein Datum - anzulegen, was bei jeder Änderung aktualisiert wird.

    Wenn du nun beim starten oder beenden des Programmes synchronisiertst, vergleichst du einfach die Änderungsdaten der Server und Lokalversion und überschreibst einfach immer die älteren Daten durch die neueren...

    Ist nicht perfekt, aber geht. Das Problem bei soetwas ist immer, wenn zwei Personen gleichzeitig am selben Datensatz arbeiten... Da du nicht permanent online bleibst...

    Sprich: Dein Rechner synchronisiert sich um 9 Uhr morgens beim Start...
    Um 11 Uhr aktualisiert jemand einen Datensatz...
    Um 11:30 Uhr aktualisierst du selbigen Datensatz... (jedoch ohne Kenntnis vom neuen Stand).
    Um 16 Uhr aktualisierst du die Datenbank... Da deine Version die Aktuellere ist, gehen die Änderungen von 11 Uhr verloren...

    MaThoPa1973 schrieb:

    Auf Grund dessen das Kunde A entweder durch den Benutzer an Platz X aber nicht durch Benutzer an Platz Y bedient wird sollte es hinsichtlich der Parallelität keine Probleme geben.

    Also wenn das sichergestellt ist, oder wenn du das sicherstellen kannst, dann ist das parallelitäts-problem gelöst.
    Ansonsten kann das noch Knackpunkt werden.
    Eine Überlegung wäre, für Platz x unzulässige Datensätze erst gar nicht nach Platz y zu schaufeln. Das würde auch den Traffic entlasten.

    Aber kannste erstmal zurückstellen und im Hinterkopf behalten.
    Hallo Zusammen,
    erst einmal vielen Dank für die vielen konstruktiven Gedankenansätze.

    @Hempelchen: Danke, die Idee mit dem Zeitstempel in jedem Datensatz ist nicht schlecht. So bräuchte ich wirklich nur in einer For/Next-Schleife jeden Datensatz die Zeitstempel abgleichen lassen, ist ein Zeitstempel geändert (jünger als der eingetragene) dann soll der Datensatz in der Zentraldatenbank geändert werden - sonst bleibt der Datensatz wie er ist.

    @ErfinderDesRades: Nun, bei den "Kunden" handelt es sich in der Realität um Patienten - Die Patientenstammdaten ändern sich nur in den seltensten Fällen und in der Wertetabelle werden bei Kontrolle nur die INR-Werte eingetragen - hier ist es bald noch seltener als z.B. eine Adressänderung im Stammdatensatz - dass hier mal ein bestehender Wert geändert wird. Also in 99,999% der Fälle werden immer nur neue Messwerte hinzugefügt aber nicht bestehende verändert. Und das eben immer nur von einem Arbeitsplatz aus - entweder der Patient sitzt in Behandlungszimmer A, B, C oder D. Insofern kann das Parallelitätsproblem zu 99,999% ausgeschlossen werden.

    Durch die Synchronisation der Datenbanken bei Programmstart und Programmende will ich zudem auch den Traffic im Netzwerk so gering wie möglich halten und natürlich auch die Netzwerksicherheit auf einem möglichst hohen Niveau halten. Der Abgleich ist aber erforderlich um die Betreuung aller Patienten von allen Arbeitsplätzen zu ermöglichen - und das auch immer mit einem möglichs aktuellen Datenbestand da dieser Einfluss auf die Ergenisse hat.

    So, ich werde mal weiter an der Routine tüffteln um den Abgleich ans laufen zu bekommen. Problem hier bei VB 2010 ist halt nur, dass VB 2010 Visual Studio einem jedes mal die Datenbank im Debug-Modus wieder in den Ursprungszustand versetzt und man so nicht wirklich den Abgleich überprüfen kann :(

    Wenn noch jemand einen Tipp oder ein Idee hat - ich bin für jede Unterstützung dankbar.

    Gruß
    Markus
    Die Datenbankdatei hat Eigenschaften im ProjektExplorer, da kann man das abstellen.

    Aber ebensogut kann man die Einstellung auch lassen, und einen Reload-button bereitstellen, mit dem man erfolgreiche Abspeicherungen im selben Testlauf überprüfen kann.

    ist eh sehr nützlich, so ein reload-Button.
    Jetzt habe ich es soweit, dass ich die Tabellen der lokalen Datenbank mit einem TableAdapter verbunden habe um da soweit alles erforderliche auslesen kann. Nur jetzt stellen sich gleich zwei weitere Probleme, bzw. Fragen...

    1. Kann man einen TableAdapter Dynamisch einer Datenbanktabelle zuordnen? Hintergrund der Frage ist der, weil sich ja die zentrale Datenbank an einem x-beliebigen Ort in den Weiten des betreffenden Netzwerkes befindet. Innerhalb des Programmes kann ausgewählt werden wo man die zentrale Datenbank abgelegt hat - entsprechend wird der Pfad der zentralen Datenbank in einer Programmsystemdatei hinterlegt. Diese wird ausgelesen um den ConnectionString zu komplettieren. Nur wo und wie kann man den ConnectionString eines TableAdapters dynamisch programmieren?

    2. Wie kann ich die Daten von einem TableAdapter (lokale Datenbanktabelle) an den TableAdapter (zentrale Datenbanktabelle) übergeben (upload), bzw. bei Programmstart natürlich umgekehrt (Download zentrale DB an lokale DB)?

    In VB6 war das ja mit ADO.DB Recordsets und SQL alles kein Problem - viel Schreibarbeit aber im Großen und Ganzen eine einfache Sache.

    Ich danke Euch für jede Anregung.

    Gruß
    Markus
    Das macht man eiglich über die mitzuliefernde Config-Datei.
    Aber bei dir die lokalen DBs - die müssen flexibler sein, newahr?

    dafür habichmal ein Hack gemacht, bei dem das eiglich schreibgeschützte Setting zur Laufzeit doch änderbar ist. suche auf AVB-upload nach "ChangeConnectionSetting".
    Hey, das ging ja schnell :)
    Leider hat es nicht geklappt, VB2010 muss konvertieren und wenn ich es dann ausprobieren will kommen eine ganze Reihe Fehler. Was ich jedoch in der ReadMe.txt gelesen habe war schon einmal ziehmlich gut.

    Gibt es denn sonst keine Möglichkeit die TableAdapter manuell im Programmcode zu erzeugen und zu parametrieren? Dann muss ich mal gucken was ich als Alternative zumindest für die zentrale Datenbank machen werde. Die Übergabe der Daten aus den TableAdaptern werde ich dann einfach über die DGV's mittels For/Next-Schleife durchnudeln.

    Ach ja - und recht hast Du... Ich brauche die Flexibilität da ich ja nicht weiß auf welchem Laufwerk die zentrale Datenbank hinterlegt sein wird. Ich gehe im übrigen umgekehrt vor - es wird keine Installation des Programms auf dem Server erfolgen sondern lokal auf den jeweiligen Arbeitsplätzen. Nur die zentrale Datenbank kann dann nach Belieben im Netzwerk abgelegt werden, man wählt im Programm mittels Drive/File den Ablageort der zentralen Datenbank aus und fertig.

    Warum? um die volle Funktionalität auch bei Netzwerkausfall zu behalten. Bei Programmstart wird quasi geprüft pb die lokale Transfertabellen (neue Datensätze, geänderte Datensätze) Datensätze enthalten. Wenn nicht, dann wurde bei der letzten Programmbeendigung der Upload auf die zentrale Datenbank durchgeführt und er führt nur einen Download von der zentralen DB aus um alle Aktualisierungen der anderen Arbeitspkätze im Speicher zu haben. Sind in den Transfertabellen Daten enthalten erfolgt erst der Upload und dann der Download. Zuvor wird aber auch erst geprüfz, ob a) überhaupt eine Anbindung an eine zentrale Datenbank gewünscht und hinterlegt ist und b) ob die zentrale Datenbank verfügbar ist.

    Aber so sollte gwährleistet sein, dass das Programm bei totalem Netzwerkausfall seine volle Funktionalität behält und sich nach einem Ausfall und wieder zur Verfügung stehendem Netzwerk automatsich updated.
    Hilfe! Ich bin ja nun schonmal einen ganzen Schritt weiter!
    Unter Verwendung folgender Vorgehensweise...

    1. Neue Datensätze werden nicht nur in die Haupttabelle der lokalen Datenbank geschrieben sondern parallel auch in die Transfertabelle "New"

    2. Wie unter 1. beschrieben wird auch mit geänderten Datensätzen verfahren... oder sagen wir soll verfahren werden.

    In folgender Zeile ist ein Syntax-Fehler und ich sehe den Wald vor lauter Bäumen nicht!

    Kurz zur Info - der Datensatz der geändert werden soll ist in einem unsichtbaren DGV, Cells 3 & 4 sind vom Typ Decimal, 0 & 1 Typ String, 2 ist Type Date. Datentypen stimmen überein - es ist ja auch "nur" ein Syntax-Fehler den ich bekomme und nicht wegen einer Datentypenunverträglichkeit!

    cmd.CommandText =
    "Update PatData Set PatM = '" & Me.PatDatChg.CurrentRow.Cells(3).Value & "', " &
    "PatKG = '" & Me.PatDatChg.CurrentRow.Cells(4).Value & "', " &
    "WHERE PatName = '" & Me.PatDatChg.CurrentRow.Cells(0).Value & "' " &
    "AND PatVName = '" & Me.PatDatChg.CurrentRow.Cells(1).Value & "' " &
    "AND PatGDat = '" & Me.PatDatChg.CurrentRow.Cells(2).Value & "'"

    Egal ob ich mit oder ohne Hochkommata ' arbeite, mit oder ohne Leerzeichen... irgendwo steckt ein Fehler und ich bin scheinbar im Augenblick zu blöde diesen zu erkennen.

    Danke für jeden der mir hilft die Augen zu öffnen.

    Gruß
    Markus
    Hi,

    ich kann dir bei deinem Problem nicht wirklich weiter helfen.
    Aber ich hätte eine generelle Frage bzgl der Syncronisation die du 2x(morgens/abends) durchführen willst.

    Warum Synchronisierst du nicht bei jeder Änderung? Wenn die Daten morgens synchronisiert werden und kurz vor Feierabend der Rechner abstürtzt sind alle Daten die in der Zeit bearbeitet wurden weg.
    Gleiches auch bei einem Stromausfall oder Netzwerkproblemen.

    mcdt schrieb:

    Hi,

    ich kann dir bei deinem Problem nicht wirklich weiter helfen.
    Aber ich hätte eine generelle Frage bzgl der Syncronisation die du 2x(morgens/abends) durchführen willst.

    Warum Synchronisierst du nicht bei jeder Änderung? Wenn die Daten morgens synchronisiert werden und kurz vor Feierabend der Rechner abstürtzt sind alle Daten die in der Zeit bearbeitet wurden weg.
    Gleiches auch bei einem Stromausfall oder Netzwerkproblemen.


    Dann müsste er aber auch immer Zugang zum Server haben, oder rumbasteln, dass er bei einer fehlerhaften Synchronisation die Daten bei der Nächsten mit übergibt...
    Hallo mcdt,
    Grund für die nur 2malige Synchronisation ist einzig um den Netzwerktraffic so gering wie möglich zu halten. Darüber hinaus ist die ganze Angelegenheit so geplant, dass die 2 malige Synchronisation vollkommen ausreichend ist. Außerdem soll die volle Funktionalität gewährleistet sein auch wenn das Netzwerk mal ausgefallen ist - denn generell arbeitet das Programm über die lokale Datenbank. Die Synchronisation am Abend dient dem Zwecke die am Tage erworbenen Daten auf die Zentraldatenbank zu spielen und die am Morgen um sich einen möglichst kompletten Daten aller Arbeitsplätze sich in die lokale Datenbank zu spielen.
    Sind die Transfertabellen (neu/geändert) bei Programmstart noch gefüllt stand das Netzwerk beim letzten Programmende nicht zur Verfügung und es wird, insofern das Netzwerk und die Zentraldatenbank verfügbar ist, erst auf die Zentr.-DB gespielt und im Anschluss gelesen. Nach dem Aufspielen auf die Zentr.-DB werden die Transfertabellen geleert. So ist erkennbar ob eine Synchronisation in Richtung Zentr.-DB erfolgt war oder nicht.
    Und was natürlich ein Grund ist, wie soll man zentral synchronisieren wenn zwischendurch das Netzwerk - warum auch immer - nicht verfügbar ist?! So habe ich jedenfalls gewährleistet immer voll funktionsfähog arbeiten zu können.

    Gruß
    Markus
    @Hempelchen
    Das "rum basteln" beim syncronisieren bleibt dem TE aber auch bei seiner aktuellen lösung nicht erspart, da es ja beim Start/Stop des Programms ebenfals zu Verbindungsproblemen kommen kann.
    Ein durchgängiger Zugriff auf den Server ist meiner Meinung nach vorraussetgzung , sollte dies nicht der Fall sein kann ich das Programm auch nicht zu beliebiger Zeit starten / beenden.

    @MaThoPa1973
    Ich will deine Methode nicht infrage stellen, habe mir nur meine Gedanken bzgl der "Usability" gemacht.
    Das Synchronisieren der DB bei Änderung und nicht 2x täglich hätte den Vorteil das im "Fehlerfall" weniger Datenverlust vorkommt.
    Angenommen ein MA bearbeitet einige Datensätzte ohne das dieses am Ende des Programms "gesynct" werden können.(Netzwerkfehler/BlueScreen/...), dieser MA kommt am nächsten Tag 3 Stunden später zur Arbeit und ein andere MA bearbeitet die "alten" Datensätzte, da der Datensatzt noch nicht aktualisiert werden konnte weil der MA der die Datensätze am Vortag bearbeitet hatr seinen Rechner / Programm noch nicht gestartrt hat. Dieses Szenario könnte nicht vorkommen, bzw mit weniger großen Auswirkungen wenn bei Änderung "gesynct" wird.

    mfg
    Hallo,

    zu Deinem Syntaxproblem. Ich würde behaupten, dass es mit ziemlicher Sicherheit an der als Date formatierten Spalte liegt.
    Versuchs mal so:

    VB.NET-Quellcode

    1. "AND PatGDat = " & Replace("#" & Format(Me.PatDatChg.CurrentRow.Cells(2).Value, "dd/MM/yyy") & "#", ".", "/")


    Kann aber gut möglich sein, dass das auch noch nicht klappt weil das u.a. von der verwendeten Db, den Systemeinstellungen usw. abhängt.
    Ist vielleicht auch noch nicht die eleganteste Methode, aber bei mir hat's so geklappt.

    Gruß Thilo