Zum Inhalt springen

Rowlock...Datensatz sperren


Empfohlene Beiträge

Geschrieben

Hallo,

folgende Situation: Anwender1 lässt sich die Daten anzeigen, wählt nen Datensatz aus (geschieht alles über ne GUI) und will den nun ändern. Jetzt will ich vermeiden das Anweder2 den Datensatz genau in diesem Moment löscht. Weil kann ja sein, dass Anwender1 unheimlich langsam ist, zwar schon im Änderungsmodus, Anweder2 aber doch schneller war.

Ich dachte ich könnte das irgendwie mit RowLock lösen, dass ich quasi den Datensatz wenn der Anwender1 auf "Bearbeiten" klickt einfach nochmal aus der DB lese und sperre. So lange wie Anwender1 dann brauch zum bearbeiten kann ihn dann kein andere bearbeiten und auch nicht löschen. Ist das irgendwie möglich mit MS SQL?

Wenn ich den Datensatz mit "Select * from tabelle_xyz with(rowlock) where id=1" ist hole bringt mir das ja nix, weil das ja nur für diese winzig kurze zeit gesperrt ist.

Jemand ne Idee?

Geschrieben

füg 2 neue spalten in die tabelle ein.

[locked_for] <- der user der den datensatz aktiv grade "hat"

[locked_at <- timestamp wann der datensatz gelockt wurde.

Bau im Frontend ein, dass ein User, der erste, den Datensatz "schreibgeschützt" hat, und bau auch ein, dass nach x minuten, er den Schreibschutz nicht mehr inne hat.

Viel Spass sowas nachträglich einzubauen, aber in irgendeiner weise musst du sowas einbauen, weil du von der Datenbank an sich kein Event geschmissen bekommen kannst, wenn sich ein Datensatz geändert hat. D.h. in dem Moment wo 2 User gleichzeitig einen Datensatz laden und verändern können, hast du ein tierisches Problem, weil die 2 sich dann gegenseitig die Änderung überschreiben.

Wie gesagt have fun, sowas nachträglich is hässlich und aufwendig.

Gruß

Sven

Geschrieben

Die Lösung von streffin ist leider nicht ganz wasserdicht, denn wenn Du prüfst, ob deine neue Spalte schon gefüllt ist, kann diese schon aktualisiert aber noch nicht committet sein. Damit überschreibst Du kurze Zeit später den Wert den die andere Session reingeschrieben hat. Was passiert, wenn die Rechnerzeit nicht stimmt oder wenn sich ein User mehrfach angemeldet hat wollen wir hier gar nicht weiter vertiefen.

Grundsätzlich gibt es zwei unterschiedliche Herangehensweisen: Das optimistische und das pessimistische Locking. Pessimistisches Locking wie Du es vorhast hat einen entscheidenden Nachteil: geht der Anwender in die Mittagspause, so sperrt er für diese Zeit den Datensatz (und ist sich dessen vielleicht nicht mal bewußt). Die Implementierung ist allerdings recht einfach. Es gibt beim SELECT die Option FOR UPDATE:

SELECT ... FROM ... WHERE ... FOR UPDATE
Damit sind die selektierten Datensätze bis zum Ende der Transaktion exclusiv gelockt. Die elegantere Methode ist das optimistische Locking. Hierzu fügst Du ein weiteres Feld in jde Tabelle ein, für die Du dies implementieren möchtest. Idealerweise ein Timestamp Feld, das auf ms Ebene anzeigt. Wird der Datensatz geladen, so selektierst Du das Feld und merkst dir den Wert im Programm. Speichert der Anwender seine Daten, so ergänzt Du Deinen Update wie folgt:
UPDATE ... SET ...,dstimestamp=aktueller_timestamp WHERE id=... AND dstimestamp=der_vorher_gemerkte_wert

Läuft der Update durch und ändert einen Datensatz, ist alles ok. Ändert der Update aber 0 Zeilen, dann wurde das Timestamp Feld schon von einer anderen Session geändert und dementsprechend dürfen diese Daten nicht ohne Rückmeldung überschrieben werden.

Andere Möglichkeiten das sauber hinzubekommen gibt es nicht.

Dim

Geschrieben

Moin,

ich kann dem Doktor da nur zustimmen, die optimistische Variante mit dem Timestamp-Feld ist handlich und praktikabel und reicht für uns Kassenpatienten völlig aus.

Die Implementierung ist allerdings recht einfach. Es gibt beim SELECT die Option FOR UPDATE:

SELECT ... FROM ... WHERE ... FOR UPDATE

Damit sind die selektierten Datensätze bis zum Ende der Transaktion exclusiv gelockt.

Bist du dir da sicher, das das so mit MS-Sql geht? Mein MS-SQL-Server 2005 versteht die Klausel "for update" jedenfalls nicht. Ich lerne da aber gern was dazu.

Reinhold

Geschrieben

Bist du dir da sicher, das das so mit MS-Sql geht? Mein MS-SQL-Server 2005 versteht die Klausel "for update" jedenfalls nicht. Ich lerne da aber gern was dazu.

Reinhold

Hmm erwischt. Da hab ich mal wieder Oracle auf auf andere Datenbanken übertragen ohne nachzuforschen ob es das dort gibt.

Dim

Geschrieben

wenn man "mssql select for update" in google hineinwirft sagt es :

select <columns> from <table> WITH 

[TABLOCK]   -- (or ROWLOCK, or HOLDLOCK )

scheint also auch in mssql das gleiche vorgehen, nur eben andere Syntax (falls mal jemand hier landet)

@Threadersteller:

versuch mal den Holdlock - das wird das sein was du suchst..

Geschrieben
mh leider hilft mir auch holdlock nicht weiter... hatte ich natürlich auch direkt ausprobiert.

Doch doch, HOLDLOCK hilft dir weiter.

Du musst natürlich darauf achten, auch eine entsprechende Transaktion zu setzen.

Alternativ zum HOLDLOCK Table Hint kannst du auch den Transaction Isolation Level für diese Transaktion auf SERIALIZABLE setzen.

Der ROWLOCK Table Hint allein wird in deinem Fall nicht funktionieren.

Du kannst allerdings über ROWLOCK in Verbindung mit XLOCK eine exklusive Sperre auf dem Datensatz setzen (Das verhindert für andere Benutzer dann aber auch die Anzeige des Datensatzes).

Goos

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...