Freigeben über


SPEICHERN TRANSAKTION (Transact-SQL)

Gilt für:SQL ServerAzure SQL-DatenbankVerwaltete Azure SQL-InstanzSQL-Datenbank in Microsoft Fabric

Legt einen Sicherungspunkt in einer Transaktion fest.

Transact-SQL-Syntaxkonventionen

Syntax

SAVE { TRAN | TRANSACTION } { savepoint_name | @savepoint_variable }
[ ; ]

Arguments

savepoint_name

Dies ist der Name, der dem Sicherungspunkt zugewiesen ist. Sicherungspunktnamen müssen den Regeln für Bezeichner entsprechen, sind jedoch auf 32 Zeichen begrenzt. bei savepoint_name wird immer die Groß-/Kleinschreibung beachtet, auch wenn bei der Datenbankmodulinstanz keine Groß-/Kleinschreibung beachtet wird.

@savepoint_variable

Dies ist der Name einer benutzerdefinierten Variablen, die einen gültigen Sicherungspunktnamen enthält. Die Variable muss mit einem der folgenden Datentypen deklariert werden: char, varchar, nchar oder nvarchar. Mehr als 32 Zeichen können an die Variable übergeben werden, aber nur die ersten 32 Zeichen werden verwendet.

Remarks

Sie können einen Speicherpunkt innerhalb einer Transaktion festlegen. Der Speicherpunkt definiert einen Konsistenzstatus, an den eine Transaktion zurückgeben kann, wenn ein Teil der Transaktion bedingt abgebrochen wird. Wenn eine Transaktion auf einen Speicherpunkt zurückgesetzt wird, muss sie bei Bedarf und einer COMMIT TRANSACTION Anweisung mit mehr Transact-SQL Anweisungen abgeschlossen werden, oder sie muss vollständig abgebrochen werden, indem die Transaktion wieder an den Anfang zurückgesetzt wird. Verwenden Sie das Formular ROLLBACK TRANSACTION transaction_name, um eine gesamte Transaktion abzubrechen. Alle Anweisungen oder Prozeduren der Transaktion werden rückgängig gemacht.

Doppelte Speicherpunktnamen sind in einer Transaktion zulässig, aber eine ROLLBACK TRANSACTION Anweisung, die den Speicherpunktnamen angibt, setzt die Transaktion nur mit diesem Namen zurück auf den neuesten SAVE TRANSACTION Namen zurück.

SAVE TRANSACTION wird in verteilten Transaktionen, die entweder explizit mit BEGIN DISTRIBUTED TRANSACTION einer lokalen Transaktion gestartet oder höhergestuft wurden, nicht unterstützt.

Hinweis

Das Datenbankmodul unterstützt keine unabhängig verwaltbaren geschachtelten Transaktionen. Ein Commit einer inneren @@TRANCOUNT Transaktion wird erhöht, hat jedoch keine anderen Auswirkungen. Ein Rollback einer inneren Transaktion führt immer einen Rollback der äußeren Transaktion durch, es sei denn, ein Speicherpunkt ist vorhanden und wird in der ROLLBACK Anweisung angegeben.

Sperrverhalten

Eine ROLLBACK TRANSACTION Anweisung, die eine savepoint_name gibt alle Sperren frei, die über den Speicherpunkt hinaus abgerufen werden, mit Ausnahme von eskalierten und konvertierten Sperren. Diese Sperren werden nicht freigegeben, und sie werden nicht wieder in den vorherigen Sperrmodus konvertiert.

Permissions

Erfordert die Mitgliedschaft in der Rolle public.

Examples

Die Codebeispiele in diesem Artikel verwenden die AdventureWorks2025- oder AdventureWorksDW2025 Beispieldatenbank, die Sie von der Microsoft SQL Server Samples and Community Projects Homepage herunterladen können.

Das folgende Beispiel zeigt, wie Sie mithilfe eines Transaktionsspeicherpunkts nur die Änderungen einer gespeicherten Prozedur zurücksetzen, wenn eine Transaktion gestartet wird, bevor die gespeicherte Prozedur ausgeführt wird.The following example shows how to use a transaction savepoint to rollback only the changes made by a stored procedure if a transaction is started before the stored procedure is executed.

IF EXISTS (SELECT name FROM sys.objects
           WHERE name = N'SaveTranExample')
    DROP PROCEDURE SaveTranExample;
GO

CREATE PROCEDURE SaveTranExample
    @InputCandidateID INT
AS
-- Detect whether the procedure was called
-- from an active transaction and save
-- that for later use.
-- In the procedure, @TranCounter = 0
-- means there was no active transaction
-- and the procedure started one.
-- @TranCounter > 0 means an active
-- transaction was started before the
-- procedure was called.
DECLARE @TranCounter INT;
SET @TranCounter = @@TRANCOUNT;

IF @TranCounter > 0
    -- Procedure called when there is
    -- an active transaction.
    -- Create a savepoint to be able
    -- to roll back only the work done
    -- in the procedure if there is an
    -- error.
    SAVE TRANSACTION ProcedureSave;
ELSE
    -- Procedure must start its own
    -- transaction.
    BEGIN TRANSACTION;
-- Modify database.
BEGIN TRY
    DELETE HumanResources.JobCandidate
        WHERE JobCandidateID = @InputCandidateID;
    -- Get here if no errors; must commit
    -- any transaction started in the
    -- procedure, but not commit a transaction
    -- started before the transaction was called.
    IF @TranCounter = 0
        -- @TranCounter = 0 means no transaction was
        -- started before the procedure was called.
        -- The procedure must commit the transaction
        -- it started.
        COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    -- An error occurred; must determine
    -- which type of rollback will roll
    -- back only the work done in the
    -- procedure.
    IF @TranCounter = 0
        -- Transaction started in procedure.
        -- Roll back complete transaction.
        ROLLBACK TRANSACTION;
    ELSE
        -- Transaction started before procedure
        -- called, do not roll back modifications
        -- made before the procedure was called.
        IF XACT_STATE() <> -1
            -- If the transaction is still valid, just
            -- roll back to the savepoint set at the
            -- start of the stored procedure.
            ROLLBACK TRANSACTION ProcedureSave;
            -- If the transaction is uncommitable, a
            -- rollback to the savepoint is not allowed
            -- because the savepoint rollback writes to
            -- the log. Just return to the caller, which
            -- should roll back the outer transaction.

    -- After the appropriate rollback, return error
    -- information to the caller.
    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT @ErrorMessage = ERROR_MESSAGE();
    SELECT @ErrorSeverity = ERROR_SEVERITY();
    SELECT @ErrorState = ERROR_STATE();

    RAISERROR (
              @ErrorMessage, -- Message text.
              @ErrorSeverity, -- Severity.
              @ErrorState -- State.
              );
END CATCH
GO