Diese Frage gilt sicherlich für einen viel größeren Bereich, aber hier ist sie.
Ich habe eine grundlegende E-Commerce-App, wo Benutzer, natürlich genug, Bestellungen aufgeben können. Besagte Aufträge müssen eine eindeutige Nummer haben, die ich versuche, gerade jetzt zu generieren.
Jede Bestellung ist anbieterspezifisch. Im Grunde habe ich eine OrderNumberInfo (VendorID, OrderNumber)
Tisch. Nun muss ich jedes Mal, wenn ein Kunde eine Bestellung aufgibt, die Zahl OrderNumber
für einen bestimmten Anbieter und geben diesen Wert zurück. Natürlich möchte ich nicht, dass andere Prozesse mich dabei stören, also muss ich diese Zeile irgendwie exklusiv sperren:
begin tranaction
declare @n int
select @n = OrderNumber
from OrderNumberInfo
where VendorID = @vendorID
update OrderNumberInfo
set OrderNumber = @n + 1
where OrderNumber = @n and VendorID = @vendorID
commit transaction
Nun, ich habe gelesen, dass select ... with (updlock rowlock)
Ich habe mich mit der Frage beschäftigt, ob ich nicht doch noch ein pessimistisches Schloss finden könnte, aber ich kann das alles nicht in ein kohärentes Bild einordnen:
- Wie wirken sich diese Hinweise auf die Snapshot-Isolation von SQL Server 2008 aus?
- Führen sie Sperren auf Zeilenebene, Seitenebene oder sogar auf Tabellenebene durch?
- Wie wird es toleriert, dass mehrere Benutzer versuchen, Zahlen für einen einzigen Anbieter zu generieren?
- Welche Isolationsstufen sind hier angemessen?
- Und überhaupt - wie kann man solche Dinge tun?
EDITAR
Nur um einige Dinge klarer zu machen:
- Die Leistung in dieser speziellen Ecke der Anwendung ist absolut kein Problem: Bestellungen werden relativ selten aufgegeben und erfordern einen teuren Aufruf des Webdienstes des Anbieters, so dass eine Verzögerung von 1 Sekunde durchaus tolerierbar ist.
- Wir realmente die Bestellnummern der einzelnen Lieferanten müssen unabhängig und fortlaufend sein