2016-07-24 4 views
0

Betrachten Sie diese Tabelle zurück:Wie eine Tabelle sperren, wenn die Auswahl Datensätze keine Daten

| id | objId | fieldNumber | 
|------|-------|-------------| 
| 902 | 1  | 1   | 
| 908 | 1  | 2   | 
| 1007 | 1  | 3   | 
| 1189 | 8  | 1   | 
| 1233 | 12 | 1   | 
| 1757 | 15 | 1   | 

ich einen neuen Rekord für eine nicht existente obj eingeben möchten. Sagen wir ObjId: 16. Die Feldnummer muss für jedes Obj 16 um 1 erhöht werden. Sehen Sie sich obj an: 1. Wie Sie sehen können, steigt es um 1. Wenn zwei oder mehr Datenbankverbindungen versuchen, obj 16 gleichzeitig einzufügen Zeit hätte ich zwei Obj 16 mit Feldnummer 1. Das kann nicht passieren. Ich muss garantieren, dass die Feldnummern nicht gleich sind und um eins erhöht werden müssen.

Also meine Lösung ist alle Datensätze von Objid erhalten. Wenn mindestens ein Datensatz vorhanden ist, legen Sie eine Sperre für alle Datensätze nach diesem Objekt fest und fügen Sie dann einen Datensatz mit der nächsten Feldnummer ein.

Alternativ, wenn ich alle Datensätze von Objid bekomme. Wenn es keine Datensätze gibt, werde ich die ganze Tabelle sperren und dann einen Datensatz mit Feldnummer 1 einfügen.

Wie würde ich eine Sperre auf den ganzen Tisch platzieren? Lassen Sie mich wissen, wenn Sie eine bessere Idee haben, dies zu tun?

Antwort

1

Wenn Sie mit Ausnahmen umgehen können, ist der einfachste Weg, eine eindeutige Integritätsbedingung für (objid, fieldnumber) hinzuzufügen.

Dann können Sie eine Abfrage ausführen, wie zum Beispiel:

insert into t(objid, fieldnumber) 
    select @objid, coalesce(max(fieldnumber) + 1, 1) 
    from t 
    where objid = @objid; 

Wenn zwei Threads gleichzeitig versuchen, die Abfrage auszuführen, dann ist die eindeutige Einschränkung fehl - und der Faden erneut versuchen.

Sie können auch den Tabellenhinweis SERIALIZABLE verwenden (der erklärt wird here).

0

Es scheint, dass objId und fieldNumber zusammen (sollte) den Primärschlüssel für diese Tabelle bilden. Auf diese Weise normalisiert, wird die Beschränkung automatisch erzwungen. Ich denke, das ist eine "sauberere" Lösung. Aber wenn Sie ein automatisch nummerierendes PK-Schema nicht löschen können, dann ist Gordons Lösung unschlagbar.

Verwandte Themen