Korrekte Isolationsstufe für SQL-Befehl

Ich möchte diese SQL-statement ausführen, um einen neuen Rang in die Rang-Tabelle einzufügen. Der Primärschlüssel rank_id ist ein char-Feld, also ist es nicht automatisch inkrementiert. Also ich benutze TOP Keyword, um die letzte ID zu erhalten und dann in SQL zu erhöhen.

 const string InsertStatement = @"BEGIN DECLARE @ID INT = (SELECT TOP 1 (rank_id + 1) FROM Rank ORDER BY [rank].rank_id DESC) INSERT INTO RANK (rank_id, rank_name, shift_rate, revised_date) VALUES (@ID, @rank, @rate, @date) END" 

Ich denke, dass ich diese Transaktion behandeln sollte, um zu vermeiden, dass schmutzig liest, andere weise ein anderer Benutzer könnte eine falsche ID als die letzte lesen. Hab ich recht? Was ist dann die richtige Isolationsstufe für eine solche Situation? Was ist damit …

 using(var Trans = sqlConnection.BeginTransaction(IsolationLevel.Serializable)) 

Sie könnten dies aus dem SQL-Ende anpacken. Das Folgende kann den Trick machen:

 INSERT RANK (rank_id, rank_name, shift_rate, revised_date) select max(rank_id) + 1, @rank, @rate, @date from RANK 

Es ist eine einzige Aussage und damit eine Atom-Transaktion – das heißt, es bekommt seine eigene Sperre (s) auf dem Tisch (und Index, wenn es eine gibt), um sicherzustellen, dass kein anderer gleichzeitiger Ablauf der exakt gleichen Abfrage "greifen" kann nächster Wert.

Dirty Lesungen sind alles andere als unmöglich, da alles in einer einzigen (und wahrscheinlich extrem schnellen) Aussage gemacht ist. Das bekommt man Atomocity – einzelne Aussagen sind immer innerhalb ihrer eigenen "impliziten Transaktion" gebunden. Slap eine Primärschlüssel-Einschränkung auf die Spalte, und Sie sollten getan werden.

Ich fühle mich verpflichtet zu erwähnen, dass Sie Probleme haben, wenn es nicht-numerische Werte in Ihrer characterspalte gibt …