Forums Neueste Beiträge
 

einzelnen Datensatz für Leseoperation sperreen

26/11/2008 - 16:48 von Carsten Ilwig | Report spam
Hallo Leute,

wie kann ich folgendes Problem lösen:

Ich habe eine Tabelle mit 5 Datensàtzen (es können auch mehr, oder weniger
sein).
Ich muss nun sicherstellen, dass wenn ein User einen der 5 Datensàtze
bearbeiten will, kein andere an den DS rankommt, auch nicht lesend.
Die anderen 4 DS sollen nicht gesperrt werden.

Beispiel:

User A will DS 3 àndern:

DS3 sperren (kein lesen und schreiben durch andere User möglich)
DS3 einlesen
DS3 àndern
DS3 sichern
DS3 wieder freigeben.

Geht das mit Bordmitteln des SQL-Servers (Version 2000) zu lösen?

Vielen Dank für Eure Hilfe.
Carsten
 

Lesen sie die antworten

#1 Günter Prossliner
26/11/2008 - 17:57 | Warnen spam
Hallo Carsten!

Ich muss nun sicherstellen, dass wenn ein User einen der 5 Datensàtze
bearbeiten will, kein andere an den DS rankommt, auch nicht lesend.



Sperren sind ein Mittel des SQL-Servers um ACID Transaktionen zu
implementieren., und kein Konstrukt welches von einem Entwickler direkt
verwendet werden.

Standardverhalten (bei ISOLATION LEVEL READ COMMITTED):

* SELECT forder Shared Lock an, welcher nach Beendigung des Statements
(nicht der Transaktion!) freigegeben wird.
* UPDATE fordert exklusiven Lock an, welcher nach der Beendigung der
Transaktion freigegeben wird.


Über Locking-Hints kann das allerdings beeinflusst werden.

User A will DS 3 àndern:

DS3 sperren (kein lesen und schreiben durch andere User möglich)


"Sperren" ist keine Aktion welche eine Entwickler (ausser App-Locks)
ausführt, das wird über Isolation-Levels und Hints gesteuert.

DS3 einlesen


"SELECT ..."

DS3 àndern


Im Code àndern? => Irrelevant

DS3 sichern


"UPDATE ..."

DS3 wieder freigeben.


Wiederrum keine Aktion ansich

Es bleiben also folgende Schritte:

1. TX starten
2. Datensatz lesen
3. Datensatz schreiben
4. TX commit


Im standardmàsigen "READ COMMITTED" Isolation Level würde eine Transaktion
TX1 bis Schritt 2 keinen exklusiven Lock anfordern, folglich kann der Record
von anderen Transaktionen gelesen werden. Du musst also schon beim SELECT
einen exklusiven Lock anfordern ==> XLOCK Hint

Ein "HOLDLOCK" ist nicht notwendig, da XLOCK das bereits inkludiert.

also zusammengefasst:

BEGIN TRAN
SELECT * FROM Tabelle WITH(XLOCK) WHERE Nr=@nr
UPDATE Tabelle SET
COMMIT

Wenn alle Transaktionen über dieses Schema abgewickelt werden funktioniert
das so.

* Innerhalb der Transaktion hast Du ja keine Benutzer-Interaktion oder?
* ggf. musst Du noch einen Index auf die "Nr" Spalte setzen (wenn noch nicht
z.b. durch PK vorhanden), und diesen mittles WITH(XLOCK, INDEX(IX_Nr)) im
Hint angegeben. Ansonsten werden die Locks im Clustered Index angefordert,
was dazu führen kann, dass auch keine Scans auf die Tabelle möglich sind.
d.h. auch ein SELECT * FROM Tabelle WHERE Nr=<freie nr> wird geblockt
werden.



OK?
mfg GP

Ähnliche fragen