Datenaktualisierung bei Mehrfachzugriff in SQL-Datenbank

  • VB.NET

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von uNki.

    Datenaktualisierung bei Mehrfachzugriff in SQL-Datenbank

    Hi,

    zur Zeit erstelle ich mein erstes Programm mit VB 2010. Daher ist die Frage eher grundlegender Natur.

    Programmbeschreibung:

    Eine SQL Datenbank hat eine Tabelle (Tabelle_1) mit der String-Spalte (Spalte_1). Die Form (Form_1) hat ein Textfeld (Textfeld_1).

    In der ersten Zeile der Datenbank wurde der Wert (Wert 1) als String eingetragen.

    Mehrere Benutzer öffnen die Datenbank und durch ein Dataset.fill wird das Dataset gefüllt, welches wiederum durch den Form.load den Wert (Wert 1) in das Textfeld (Textfeld_1) einträgt. Bei jedem Benutzer steht nun im Textfeld der Wert (Wert 1).

    Nun möchte der Benutzer_1 den Wert ändern.

    Durch Conn.open wird die Verbindung zur Datenbank geöffnet, dem Updatebefehl wird der Wert (Wert 1) in der Datenbank durch den String (Wert geändert) und Conn.close wird die Verbindung geschlossen.

    Frage: Wie kann sich der nun aktuelle Datenbankwert (Wert geändert) an die anderen Benutzer übertragen, ohne dass eine weitere Aktion durch die Benutzer erfolgt. Nach meinem Verständnis würde auch ein CommandBuilder die Datenverbindung zur Datenbank schließen.


    Zusatz zur Erläuterung... ist jedoch nicht so wichtig... nur wenn es für die obige Frage die richtige Lösung wäre...
    Eine Testumgebung mit CommandBuilder habe ich auch noch nicht hinbekommen, da ich Verständnisschwierigkeiten mit dem Datacommand habe...

    VB.NET-Quellcode

    1. daCustomers = New SqlClient.SqlDataAdapter("Select * From Customers", dcNorthwind)
    2. daCustomers.Fill(DsNorthwind1, "Customers")
    3. Dim cb As SqlClient.SqlCommandBuilder
    4. cb = New SqlClient.SqlCommandBuilder(daCustomers)


    Vielen Dank im Voraus für die Hilfe

    Romario Castanyeda

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Romario_Castanyeda“ ()


    Frage: Wie kann sich der nun aktuelle Datenbankwert (Wert geändert) an die anderen Benutzer übertragen, ohne dass eine weitere Aktion durch die Benutzer erfolgt. Nach meinem Verständnis würde auch ein CommandBuilder die Datenverbindung zur Datenbank schließen.


    Das ist immer so ein beliebtes Thema. ^^

    Prinzipiel arbeiten SQL-Server nach dem Prinzip FiFo ... also das UPDATE-Command das zuerst den Server erreicht wird auch zuerst abgearbeitet. Allerdings wäre dann bei einer Serie von Änderungen automatisch der LastIn der Gewinner, weil seine Änderung als letztes geschrieben wird und damit dann letztendlich stehen bleibt.

    Diese Verarbeitungsart ist in vielen Fällen auch genau die richtige.

    Standardmäßig kannst Du nur durch die Wahl des Lock-Modes hierauf Einfluss nehmen (Lock-Optimistic oder Lock-Pessimistic). Bei Lock-Optimistic (Default wenn ich mich nicht täusche) wird der DS nur für die Dauer der Bearbeitung für andere Zugriffe gesperrt, bei Lock-Pessimistic wird bei Zugriff schon direkt gesperrt und kein anderer User kann den DS aufrufen.

    Um Datensätze die in der Anzeige sind zu akutalisieren kannst Du aktualisieren, müsste entweder .Refresh oder .Requery sein. Damit wird der aktuellste Stand aus der DB ausgelesen.

    Aber das alle zugreifenden Connections automatisch aktualisiert werden wenn sich ein DS ändert, das gibt es nicht. Keine Chance.

    Das Standardvorgehen ist für solche Wünsche, dass man Anzeige und Bearbeitung erstmal voneinander stringent trennt. DS sind dann halt nicht mehr direkt im DataGridView zu bearbeiten. Sondern alles bekommt ein eigenes Bearbeitungsformular und wenn nun jemand einen DS der in einem DataGridView angezeigt wird bearbeiten will, klickt er auf den DS und für diesen öffnet sich dann das Bearbeitungsformular.

    Dadurch sind zwei Dinge möglich:

    1. Prüfen an Hand eines Flags ob irgendein anderer User den DS bereits zur Bearbeitung geöffnet hat
    2. Setzen eines Flags in der DB für die Anzeige an alle anderen User das der DS gerade in Bearbeitung ist.

    In der Regel besteht das Flag aus der Uhrzeit-Angabe wann die Sperrung durch einen User erfolgte. Dadurch kann man gut eine 5-Minute-Regel nutzen:

    1. Hat der User die Bearbeitungsmaske länger als 5 Minuten geöffnet, wird er gefragt ob er weiter arbeiten will oder schliessen möchte. Kommt nach x Sekunden keine Antwort, wird der Bearbeitungsmodes automatisch gequittet (damit zu lange Sperrungen vermieden werden). Bestätigt der User aber das er weiter arbeiten will, dann wird die Sperre um weitere 5 Minuten verlängert etc., etc. ... .

    Intelligent gemacht, nutzt man das in Kombo mit einer Inaktivitätsprüfung ... die Sperre wird bei jeder Eingabe/jeder Aktion des Users in der Bearbeitungsmaske automatisch verlängert und ein Timer auf 0 gesetzt. Hat der Timer irgendwann 4:30 Minuten erreicht ist klar der User hat solange nix mehr eingegeben, man fragt ihn dann noch kurz höflichkeitshalber ob er trotzdem weiter machen möchte.

    2. Jeder Sperrungs-Eintrag der älter als 5 Minuten ist in dem Sinne ungültig und kann bei der Prüfung wenn ein User den DS bearbeiten will als nicht relevant angesehen werden.

    Hoffe konnte Dir weiter helfen bei Deinem Problem. ;)

    Zum Thema CommandBuilder kann ich Dir nicht helfen weil ich das Teil eh nicht nutze.

    Gruß

    Rainer
    Danke für die richtig ausführliche Betrachtung.

    Ich werde es prüfen.

    Was ich also hieraus lerne, ist....

    Es muss ein Lesezugriff durch den 2. Benutzer (z.B. Fill-Methode) erfolgen.

    Was dem widerspricht ist folgende Erfahrung:

    Ich kenne Programme, bei dem der Schulungsleiter an seinem Client etwas in ein Textfeld einträgt (die Bearbeitung können alle Teilnehmer am Beamer mitverfolgen) und nach dem Verlassen des Datenfeldes, werden die Daten bei allen Clients der Seminarteilnehmer in dem entsprechenden Feld geändert, ohne dass die Seminarteilnehmer etwas tun. ... und ... wie funktioniert dann ein Chat?

    Romario_Castanyeda schrieb:


    Es muss ein Lesezugriff durch den 2. Benutzer (z.B. Fill-Methode) erfolgen.


    Nein, nicht beim Lesezugriff sondern nur und ausschließlich beim Schreibzugriff. Lesezugriff ist latte.


    Was dem widerspricht ist folgende Erfahrung:


    Nein, wiederspricht nicht ... das es Dir so vor kommt liegt nur daran Du meine Ausführungen falsch verstanden hast. ;)


    Ich kenne Programme, bei dem der Schulungsleiter an seinem Client etwas in ein Textfeld einträgt (die Bearbeitung können alle Teilnehmer am Beamer mitverfolgen) und nach dem Verlassen des Datenfeldes, werden die Daten bei allen Clients der Seminarteilnehmer in dem entsprechenden Feld geändert, ohne dass die Seminarteilnehmer etwas tun. ... und ... wie funktioniert dann ein Chat?


    Ganz einfach: Durch die Refresh/Requery-Methode beim Lesezugriff.

    Wobei der Chat ja nachdem von mir geschildert Grund-Prinzip arbeitet: User 1 setzt beim Schreibzugriff seine "Marke" und daher kann User 2 durch sekündliches refreshing seines Lesezugriffes genau sehen das User 1 jetzt gerade schreibt. Und wenn User 1 dann mit schreiben fertig ist und auf absenden klickt (was nix anders als speichern der Eingabe und Beenden des Schreibmodus heisst) wird seine "Marke" gelöscht und daher sieht User 2 das User 1 zu schreiben aufgehört hat. Und der regelmäßige Refresh des Lesezufgriffes sorgt dann dafür das er kurz darauf auch die Nachricht sieht.

    So simple funzt das. ;)

    Gruß

    Rainer
    da ich mich auch erst kürzlich mit diesem thema beschäftigt habe (was ist, wenn mehrere user auf den sql server zugreifen und zeitgleich daten verändern wollen), möchte ich dir auch noch ein thema mit auf den weg geben, das dir evtl. helfen könnte. habe es aus einem c# buch. überschrift des themas: "Query Notification verwenden" aus dem buch: "Visual C# 2010 Kochbuch". lässt sich sicher analog auf vb2010 anwenden.












    hier noch was allgemeines dazu:

    msdn.microsoft.com/en-us/library/62xk7953.aspx

    hoffe es hilft