SQLServer-Sperrtabelle während der gespeicherten Prozedur

8

Ich habe eine Tabelle, wo ich eine ID 99% der Zeit automatisch zuweisen muss (das andere 1% schließt mit einer Identitätsspalte aus, wie es scheint). Also habe ich eine gespeicherte Prozedur, um die nächste ID in den folgenden Zeilen zu erhalten:

%pr_e%

Bei der Überprüfung muss überprüft werden, ob Benutzer die IDs manuell verwendet haben und die nächste nicht verwendete ID finden.

Es funktioniert gut, wenn ich es seriell anrufe und 1, 2, 3 zurücksende ... Was ich tun muss, ist ein Locking, wo mehrere Prozesse dies gleichzeitig aufrufen. Idealerweise benötige ich es nur, um die last_auto_id-Tabelle um diesen Code herum zu sperren, so dass ein zweiter Aufruf warten muss, bis der erste die Tabelle aktualisiert, bevor sie ihre Auswahl ausführen kann.

In Postgres kann ich etwas wie "LOCK TABLE last_auto_id;" um die Tabelle explizit zu sperren. Irgendwelche Ideen, wie man es in SQL Server erreicht?

Vielen Dank im Voraus!

    
asc99c 10.11.2010, 10:40
quelle

5 Antworten

3

Ihr habt zwischen euch meine Frage beantwortet. Ich füge meine eigene Antwort ein, um die Arbeitslösung zu sammeln, die ich in einem Post habe. Der Schlüssel scheint der Transaktionsansatz zu sein, mit Hinweisen auf die Tabelle last_auto_id. Das Festlegen der Transaktionsisolation auf serializable scheint Deadlock-Probleme zu verursachen.

Hier ist, was ich habe (bearbeitet, um den vollständigen Code zu zeigen, hoffentlich kann ich weitere Antworten bekommen ...):

%Vor%

Dies nimmt eine exklusive Tabellensperre am Anfang der Transaktion heraus, die dann erfolgreich weitere Anfragen in die Warteschlange stellt, bis diese Anfrage die Tabelle aktualisiert und ihre Transaktion festgeschrieben hat.

Ich habe ein bisschen C-Code geschrieben, um es mit gleichzeitigen Anfragen von einem halben Dutzend Sitzungen zu hämmern und es funktioniert perfekt.

Allerdings habe ich eine Sorge, die den Begriff 'Hinweise' sperrt - weiß jemand, ob SQL Server dies als eine bestimmte Anweisung oder nur einen Hinweis behandelt (dh vielleicht wird es nicht immer gehorchen ??)

    
asc99c 10.11.2010, 12:00
quelle
5

Das folgende Update erhöht Ihre Last-ID um eins und weist diesen Wert Ihrer lokalen Variable in einer einzigen Transaktion zu.

Bearbeiten

Danke an Dave und Mitch für das Aufzeigen von Isolationsstufenproblemen mit der ursprünglichen Lösung.

%Vor%     
Lieven Keersmaekers 10.11.2010 10:45
quelle
2

Wie ist diese Lösung? Kein TABLE LOCK ist erforderlich und funktioniert einwandfrei !!!

%Vor%

Die Update-Anweisung verwendet immer eine Sperre, um das Update zu schützen .

    
Yaqub Ahmad 06.12.2012 10:19
quelle
1

Sie könnten Deadlocks in Erwägung ziehen. Dies geschieht normalerweise, wenn mehrere Benutzer die gespeicherte Prozedur gleichzeitig verwenden. Um Deadlocks zu vermeiden und sicherzustellen, dass jede Anfrage des Benutzers erfolgreich ist, müssen Sie während der Update-Fehler eine gewisse Behandlung vornehmen. Dazu benötigen Sie einen try catch. Dies funktioniert nur auf Sql Server 2005, 2008.

%Vor%     
Carls Jr. 10.11.2010 11:01
quelle
1

Ich bevorzuge dies mit einem identity -Feld in einer zweiten Tabelle. Wenn Sie lastid identity eingeben, müssen Sie nur eine Zeile in diese Tabelle einfügen und @scope_identity auswählen, um Ihren neuen Wert zu erhalten, und Sie haben weiterhin die Gleichzeitigkeitssicherheit von identity , obwohl das ID-Feld in Ihrem Haupttabelle ist nicht identity .

    
Donnie 10.11.2010 12:16
quelle

Tags und Links