SQL Server-Praxis

Anwendungssperren für einen fachlichen Vorgang

Koordinieren Sie konkurrierende Worker mit sp_getapplock und trennen Sie Sperrbereich, Fehlerbehandlung und dauerhafte Idempotenz.

Zwei Worker können gleichzeitig feststellen, dass eine Rechnung abgeschlossen werden darf, bevor einer den Abschluss speichert. Eine Eindeutigkeitsbedingung schützt möglicherweise die Rechnungsnummer, koordiniert aber nicht alle Zwischenschritte. Eine Anwendungssperre stellt kooperierenden SQL-Server-Sitzungen eine benannte Ressource für diesen fachlichen Vorgang bereit.

Ressource und Lebensdauer festlegen

Benennen Sie die kleinste fachliche Einheit, die exklusiv bearbeitet werden muss, beispielsweise invoice:481 statt all-invoices. Ein globaler Name serialisiert unnötig unabhängige Kunden. Unterschiedliche Schreibweisen erzeugen dagegen unabhängige Sperren. Zentralisieren Sie die Namensbildung und berücksichtigen Sie Mandanten, wenn Nummern nur innerhalb eines Mandanten eindeutig sind.

Die Ressource gehört zu einer Datenbank und einem Datenbankprinzipal-Namensraum. Gleicher Text in verschiedenen Datenbanken erzeugt keine gemeinsame Konkurrenz. Ressourcennamen unterscheiden Groß- und Kleinschreibung. Verwenden Sie eine kanonische Darstellung und beachten Sie die dokumentierte Längengrenze, damit abgeschnittene Namen keine unbeabsichtigten Kollisionen verursachen.

Für einen kurzen Vorgang innerhalb der Datenbank ist Transaktionsbesitz meist gut nachvollziehbar. Commit und Rollback geben die Sperre frei. Sitzungsbesitz kann sinnvoll sein, macht aber explizite Freigabe und Connection Pooling zu Teilen der Korrektheit. Eine wiederverwendete Verbindung entspricht keiner fachlichen Vorgangsgrenze.

Erwerb und Fehlerbehandlung verbinden

Führen Sie das Muster in einer Testdatenbank ohne äußere Transaktion aus. Ersetzen Sie die markierte Stelle durch die kurze Datenbankoperation. Die Prüfung des Rückgabewerts verhindert, dass geschützter Code nach einem erfolglosen Sperrversuch trotzdem läuft.

IF @@TRANCOUNT <> 0
    THROW 50000, 'This example owns its transaction.', 1;
SET XACT_ABORT ON;
BEGIN TRY
    BEGIN TRAN;
    DECLARE @rc int;
    EXEC @rc = sys.sp_getapplock
        @Resource = N'invoice:481',
        @LockMode = 'Exclusive',
        @LockOwner = 'Transaction',
        @LockTimeout = 5000,
        @DbPrincipal = 'public';
    IF @rc < 0
        THROW 50001, 'Application lock was not acquired.', 1;
    -- Read durable operation record; perform short database work.
    SELECT @rc AS LockResult;
    COMMIT;
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 ROLLBACK;
    THROW;
END CATCH;

Ein nichtnegativer Rückgabewert bedeutet erfolgreichen Erwerb. Negative Werte kennzeichnen beispielsweise Timeout, Abbruch oder eine Deadlock-Auswahl. Das Beispiel behandelt alle Erwerbsfehler als gescheiterte Operation und rollt zurück. Produktionscode kann diese Fälle für Protokollierung und begrenzte Wiederholungen unterscheiden, darf sie aber nicht als Freigabe zum Weiterarbeiten behandeln.

Das Timeout von fünf Sekunden betrifft nur den Erwerb dieser Anwendungssperre. Es begrenzt weder spätere Zeilensperren noch Netzwerkverzögerungen oder die Gesamtdauer des Vorgangs. Definieren Sie zusätzlich ein Anfragebudget und stellen Sie nach einem Abbruch die Bereinigung der Transaktion sicher.

Öffnen Sie zum Test in Fenster A eine Transaktion und erwerben Sie die Ressource ohne Abschluss. Fenster B sollte nach seinem Timeout scheitern. Rollen Sie A zurück und wiederholen Sie B; jetzt sollte der Erwerb gelingen. Prüfen Sie zusätzlich verschiedene Rechnungsressourcen, die unabhängig voneinander laufen müssen. Beenden Sie die absichtlich offene Übungstransaktion ausdrücklich.

Dauerhafte Zusagen separat speichern

Geschützt sind nur Zugriffswege, die dieselbe Ressource erwerben. Direkte Administratoränderungen oder alte Anwendungsversionen können die Konvention umgehen. Behalten Sie Eindeutigkeitsbedingungen, Fremdschlüssel und die Prüfung zulässiger Zustandswechsel bei. Koordination ersetzt kein korrektes Datenmodell.

Nach der Freigabe erinnert sich die Sperre nicht an einen erfolgreichen Abschluss. Geht die Antwort nach Commit verloren, kann eine Wiederholung die Ressource erneut erwerben. Speichern Sie deshalb eine dauerhafte Vorgangskennung und das Ergebnis zusammen mit der fachlichen Änderung. Lesen Sie diesen Datensatz unter der Sperre zuerst und liefern Sie bei einer Wiederholung das vorhandene Ergebnis.

Halten Sie die Transaktion nicht während eines Zahlungsdienstaufrufs offen. Ein Datenbankrollback nimmt eine erfolgreiche externe Belastung nicht zurück. Schreiben Sie stattdessen einen Outbox-Eintrag atomar und verarbeiten Sie ihn über einen idempotenten Auslieferungspfad. Benötigt eine Transaktion mehrere Ressourcen, erwerben Sie diese stets in derselben Reihenfolge. Auch Anwendungssperren können Teil eines Deadlocks sein. Messen Sie Wartezeit, Erwerbsfehler und Transaktionsalter, damit konkurrierende Vorgänge kontrolliert warten und unabhängige Vorgänge parallel bleiben.

Technische Referenzen: Microsoft Learn: sp_getapplock · Microsoft Learn: sp_releaseapplock.

Frage zu diesem Artikel

Haben Sie eine Frage zu diesem Thema?

Beschreiben Sie, was Sie bewerten oder wo Sie nicht weiterkommen. Wir antworten mit einer praktischen Empfehlung.

Inquiries are not enabled in this preview.

Eine Frage zu diesem Artikel stellen