Frage

Das Problem, das ich habe, ist dies:

Ich habe eine Tabelle (nur ein Beispiel) mit den folgenden Feldern:

ID int
Value int

Ich habe eine Methode namens IncreaseByFive (), die macht folgendes:

method IncreaseByFive(int ID)
{    
    int value = GetValueFromDB(ID);
    value = value + 5;
    SaveValueToDB(value, ID);    
}

Was ich vermeiden möchte, ist die folgende Situation vor:

  1. Benutzer A ruft Methode und erhält den Wert (derzeit 5)
  2. Benutzer B ruft Methode und erhält den Wert (derzeit 5)
  3. User A erhöht Wert von 5 (jetzt 10)
  4. User B erhöht Wert von 5 (jetzt 10)
  5. Benutzer A speichert Wert (10)
  6. User B speichert Wert (10)

Jetzt hat der Datensatz einen Wert von 10, wenn es 15 gewesen sein sollte.

Was soll ich zwingen, ist die folgende:

  1. Benutzer A ruft Methode und erhält den Wert (derzeit 5)
  2. Benutzer B ruft Methode hat aber zu warten, weil ein bereits es nannte. (Dibs!)
  3. User A erhöht den Wert (jetzt 10)
  4. Benutzer B noch wartet
  5. Benutzer A speichert den Wert (Spitzenwert von 10 hat)
  6. User B kann nun den Wert lesen (10)
  7. User B erhöht den Wert (15)
  8. User B speichert den Wert

Jetzt hat der Datensatz einen Wert von 15, die das Ergebnis, denn ich bin auf der Suche ist.

ich dieses Problem in der Vergangenheit gelöst haben eine statische Klasse verwenden und eine Sperre auf ein statisches Objekt im Konstruktor dieser Klasse erzeugt setzen, damit die ganze Arbeit durch eine statische Methode schleusen, die anderen Anrufe zwingt in der Schlange warten . Ich fürchte jedoch, dass dies nicht skalierbar ist.

Ich denke auch, dass das die höchste Isolationsstufe (serializable) für eine Transaktion wird nicht den Trick entweder, weil es der Lese in Schritt 2 des unerwünschten Beispiels oben ermöglicht.

Ich nehme an einem anderen Lösung wäre, meine eigene Sperrtabelle zu erstellen und die Sperren dort aufnehmen, aber das scheint, wie es nicht notwendig sein sollte.

Ich entwickle dieses Projekt mit C # (3.5) und SQL Server 2008.

Was bedeutet die hive mind denken?

War es hilfreich?

Lösung

Vielleicht bin ich über diese underthinking, würde aber nicht einfach in den gesamten Logikblock wickeln ..

  • lesen Wert
  • Schreibwert

in einer Datenbanktransaktion der entsprechenden Ebene?

SET TRANSACTION ISOLATION LEVEL
    { READ UNCOMMITTED
    | READ COMMITTED
    | REPEATABLE READ
    | SNAPSHOT
    | SERIALIZABLE
    }
[ ; ]
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top