Mehrfaches Öffnen und Speichern eines Datensatzes verhindern

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    Mehrfaches Öffnen und Speichern eines Datensatzes verhindern

    Guten Tag zusammen,

    ich bin momentan dabei ein Programm mit einer Datenbankanbinung zu schrieben, welches von mehreren Benutzern gleichzeitig genutz werden soll.

    Über ein Auswahl in einem DataGridView wird eine neue Form mit Informationnen aus der Datenbank geöffnet.
    Ich möchte nun, ähnlich wie man es bei MS Word o.ä. kennt, verhindern, dass mehrmals der gleiche Datensatz geöffnet und gespeichert werden kann.

    Bedeutet, wenn Person A Datensatz1 öffnet sollen andere Personen, die zur gleichen Zeit den Datensatz öffnen wollen eine Meldung bekommen, dass
    Sie ihn zwar öffnen und ansehen, aber nicht abspeichern können.

    Meine Frage ist jetzt, wie bekomme ich es am einfachsten hin, dass die DB, das Programm oder wer auch immer weiß, dass ein Datensatz geöffnet ist?

    Ich weiß auch leider überhaupt nicht, wonach ich für eine Antwort googlen soll...

    Kann mir da jemand weiterhelfen?
    soweit ich weiß muss man da was recht aufwändiges selber coden.
    Etwa den Datensatz über eine StoredProc abrufen, die beim Abruf einen Timestamp in den Datensatz schreibt.
    Folgende Abrufer erkennen dann am Timestamp: "Ah - hier wird schon mit gearbeitet - seit xy."
    Dann muss noch ein TimeOut definiert werden, damit der DS nach einer Zeit auch mal wieder frei gegeben wird.
    Oder vlt. funztes so, dass man als Timestamp die Zeit reinschreibt, für die man den DS reserviert haben will - ja, so.
    Wenn man dann innerhalb der Zeit abspeichert, schreibt man natürlich einen abgelaufenen Timestamp neu rein, damit der DS sofort wieder frei ist.

    So reime ich mir das zusammen, kann sein, dasses da auch dolle Frameworks und sonstwas für Konstruktionen für gibt - ist ja eiglich ein Standard-Problem.
    Hm, ok...
    Also doch so aufwändig wie ich es mir auch ungefähr vorgestellt habe.
    Ich meine mal irgendetwas von Transactio gehört zu haben.
    Aber wenn ich danach google finde ich nur Codes und Beispiele, wo damit Übertragungen an die Datenbank gemacht werden, wenn ich das richtig interprätiert habe.

    Dann werde ich mir wohl irgendwas basteln müssen...xD

    Aber danke. :)

    Wenn noch jemand eine Idee hat, wäre ich dankbar, wenn ihr sie mir mitteilt.

    Nils schrieb:

    dass die DB, das Programm oder wer auch immer weiß, dass ein Datensatz geöffnet ist?
    Wenn du nicht mal verrätst, welche Datenbank du verwendest, wird es schwierig, dir den richtigen Einstieg zu zeigen.

    Google mal nach RowLock oder RecordLocking.

    Ich möchte nun, ähnlich wie man es bei MS Word o.ä. kennt, verhindern, dass mehrmals der gleiche Datensatz geöffnet und gespeichert werden kann.
    Word blockiert das komplette Dokument.
    Das würde dem entsprechen, dass die Datenbank nur einen Connect gleichzeitig zulässt.
    Was du möchtest, ist, einzelne Abschnitte im Dokument zu sperren, solange eine anderer Benutzer denselben Abschnitt bearbeitet.
    Das kann auch Word nicht.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

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

    Du erweiterst die Datentabelle um ein Feld, zB Status, dessen Defaultwert 0 ist, das heisst, Datensatz kann editiert werden.

    Wenn ein User den Datensatz oeffnet, fragst du zuerst dieses Feld ab. Wenn 0, dann setzt du den Wert auf 1 und der User kann editieren, etc.

    Wenn jetzt ein anderer User den gleichen Datensatz aufruft, dann ist der Wert 1, das heisst er kann nur lesen.

    Wenn der User, der auch schreiben kann, den Datensatz schliesst, dann setzt du den Wert wieder auf 0, damit ein anderer User den Datensatz auch aendern kann.

    Edit: du kannst auch den Usernamen speichern, damit den anderen Usern angezeigt werden kann, wer gerade den Datensatz editiert.

    vb_fan schrieb:

    Wenn der User, der auch schreiben kann, den Datensatz schliesst, dann setzt du den Wert wieder auf 0, damit ein anderer User den Datensatz auch aendern kann.
    Das muss die Datenbank aber selbst erledigen, sonst kriegst du bei jedes Mal, wenn das Programm oder der Benutzer nicht exakt in der von dir vorgeschriebenen Weise arbeitet, einen auf ewig gesperrten Datensatz.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Ups...habe versehentlich "Erledigt" geklickt...

    Also Word z.B. lässt einem ja auch die Möglichkeit offen das Dokument im schreibgeschützten Modus zu öffnen.
    Das ist ja genau das, was ich möchte.

    Ich werde auf jeden Fall mal nach den Begriffen schauen.
    Habe selber auch nochmal geguckt und die Begriffe Optimistic und Pessimistic Locking gefunden (codeproject.com/Articles/11426…0do%20we%20need%20locking).

    Das mit dem Status ist ja in etwas das, was ErfinderDesRades und ich am Anfang gedacht hatten.

    Ich denke, ich werde mich nochmal genauer damit befassen, wenn das Programm soweit läuft. :)

    Ich Danke Euch allen erstmal.

    vb_fan schrieb:

    Es muss so programmiert werden, dass das Feld beim Verlassen des Datensatzes auf 0 gestellt wird (zB formclosing event)
    Immer auch einen Programmabsturz oder Rechnerabsturz mit in Betracht ziehen!
    Die Datenbank muss den Lock-Vorgang an sich selbst regeln und darf sich nicht aufs Programm verlassen müssen.
    Der oben von vb_fan verlinkte CodeProject-Artikel ist da schon der richtige Ansatz.

    Nils schrieb:

    Word z.B. lässt einem ja auch die Möglichkeit offen das Dokument im schreibgeschützten Modus zu öffnen.
    Word kann das aber nur für das gesamte Dokument, nicht für einzelne Abschnitte.
    Damit kannst du während der gesamten Session nicht schreiben.

    So was kannst du in SQL auch machen.
    Du kannst dich mit einem ReadOnly-User verbinden.
    Oder dem ConnectionString die Eigenschaft ApplicationIntent=ReadOnly geben.

    Wenn ich dich richtig verstanden haben möchtest du aber mehrere Sessions parallel fahren, die grundsätzlich alle schreiben können sollen (wenn nicht gerade der Datensatz geändert sein sollte).

    Magst vielleicht doch mal verraten, welche Datenbank du nutzt und mit welcher Coding-Technik du rangehst?
    Vielleicht sogar einen Code-Ausschnitt?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --