11 Stimmen

SQL Server-Race-Bedingung Frage

(Hinweis: Dies gilt für MS SQL Server)

Angenommen, Sie haben eine Tabelle ABC mit einer Primärschlüssel-Identitätsspalte und einer CODE-Spalte. Wir möchten, dass jede Zeile in dieser Tabelle einen eindeutigen, sequentiell generierten Code hat (basierend auf einer typischen Prüfzifferformel).

Nehmen wir an, Sie haben eine weitere Tabelle DEF mit nur einer Zeile, in der der nächste verfügbare CODE gespeichert wird (stellen Sie sich eine einfache Autonummer vor).

Ich weiß, dass eine Logik wie die folgende eine Wettlaufsituation darstellen würde, bei der zwei Benutzer am Ende denselben CODE erhalten könnten:

1) Run a select query to grab next available code from DEF
2) Insert said code into table ABC
3) Increment the value in DEF so it's not re-used.

Ich weiß, dass zwei Benutzer bei Schritt 1) hängenbleiben und in der ABC-Tabelle denselben CODE haben könnten.

Wie kann man am besten mit dieser Situation umgehen? Ich dachte, ich könnte einfach ein "begin tran" / "commit tran" um diese Logik wickeln, aber ich glaube nicht, dass das funktioniert. Ich hatte eine gespeicherte Prozedur wie diese zu testen, aber ich habe nicht die Race Condition zu vermeiden, wenn ich von zwei verschiedenen Windows in MS ausgeführt:

begin tran

declare @x int

select   @x= nextcode FROM  def

waitfor delay '00:00:15'

update def set nextcode = nextcode + 1

select @x

commit tran

Kann jemand etwas Licht in diese Angelegenheit bringen? Ich dachte, die Transaktion würde verhindern, dass ein anderer Benutzer auf meine NextCodeTable zugreifen kann, bis die erste Transaktion abgeschlossen ist, aber ich schätze, mein Verständnis von Transaktionen ist fehlerhaft.

EDIT: Ich habe versucht, das Warten nach der "Update"-Anweisung zu verschieben, und ich habe zwei verschiedene Codes... aber ich vermutete, dass. Ich habe die waitfor-Anweisung dort, um eine Verzögerung zu simulieren, damit die Race Condition leicht zu erkennen ist. Ich denke, das Hauptproblem ist meine falsche Vorstellung davon, wie Transaktionen funktionieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X