SAVE TRANSACTION (Transact-SQL)

Si applica a:SQL Server database SQL di Azure Istanza gestita di SQL di Azure

Imposta un punto di salvataggio in una transazione.

Convenzioni di sintassi Transact-SQL

Sintassi

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

Nota

Per visualizzare la sintassi Transact-SQL per SQL Server 2014 (12.x) e versioni precedenti, vedere la documentazione delle versioni precedenti.

Argomenti

savepoint_name
Nome assegnato al punto di salvataggio. I nomi di punto di salvataggio devono essere conformi alle regole per gli identificatori, ma non possono contenere più di 32 caratteri. In savepoint_name viene sempre applicata la distinzione tra maiuscole e minuscole, anche quando l'istanza di SQL Server non prevede distinzione tra maiuscole e minuscole.

@savepoint_variable
Nome di una variabile definita dall'utente contenente un nome di punto di salvataggio valido. La variabile deve essere dichiarata con un tipo di dati char, varchar, nchar o nvarchar. È possibile passare alla variabile più di 32 caratteri, ma in tal caso verranno utilizzati solo i primi 32.

Osservazioni:

Un utente può impostare un punto di salvataggio o marcatore all'interno di una transazione. Il punto di salvataggio consente di contrassegnare il punto fino a cui conservare una transazione se parte della transazione viene annullata in modo condizionale. Se si esegue il rollback di una transazione fino a un punto di salvataggio, è necessario che la transazione venga completata (se necessario con più istruzioni Transact-SQL e con un'istruzione COMMIT TRANSACTION) oppure annullata completamente (tramite il rollback fino all'inizio della transazione). Per annullare un'intera transazione, usare la sintassi ROLLBACK TRANSACTION transaction_name. In tal caso, verranno annullate tutte le istruzioni o procedure della transazione.

In una transazione è consentito l'utilizzo di nomi di punto di salvataggio duplicati. Un'istruzione ROLLBACK TRANSACTION contenente un nome di punto di salvataggio, tuttavia, eseguirà il rollback della transazione solo fino all'istruzione SAVE TRANSACTION più recente che utilizza tale nome.

L'istruzione SAVE TRANSACTION non è supportata in transazioni distribuite avviate in modo esplicito con l'istruzione BEGIN DISTRIBUTED TRANSACTION o risultanti dall'escalation di una transazione locale.

Importante

Un'istruzione ROLLBACK TRANSACTION che specifica un argomento savepoint_name rilascia tutti i blocchi acquisiti oltre il punto di salvataggio, ad eccezione di escalation e conversioni. Tali blocchi non vengono rilasciati né riconvertiti alla loro precedente modalità di blocco.

Autorizzazioni

È richiesta l'appartenenza al ruolo public.

Esempi

Nell'esempio seguente viene illustrato come utilizzare un punto di salvataggio di una transazione per eseguire il rollback delle sole modifiche apportate da una stored procedure nel caso in cui sia avviata una transazione attiva prima dell'esecuzione della stored procedure.

USE AdventureWorks2022;  
GO  
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, echo 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  

Vedi anche

BEGIN TRANSACTION (Transact-SQL)
COMMIT TRANSACTION (Transact-SQL)
COMMIT WORK (Transact-SQL)
ERROR_LINE (Transact-SQL)
ERROR_MESSAGE (Transact-SQL)
ERROR_NUMBER (Transact-SQL)
ERROR_PROCEDURE (Transact-SQL)
ERROR_edizione Standard VERITY (Transact-SQL)
ERROR_STATE (Transact-SQL)
RAI edizione Standard RROR (Transact-SQL)
ROLLBACK TRANSACTION (Transact-SQL)
ROLLBACK WORK (Transact-SQL)
PROVARE... CATCH (Transact-SQL)
XACT_STATE (Transact-SQL)