Compartilhar via


SALVAR TRANSAÇÃO (Transact-SQL)

Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada de SQL do AzureBanco de dados SQL no Microsoft Fabric

Define um ponto de salvamento em uma transação.

Convenções de sintaxe de Transact-SQL

Syntax

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

Arguments

savepoint_name

É o nome atribuído ao ponto de salvamento. Os nomes de ponto de salvamento devem estar de acordo com as regras para identificadores, mas são limitados a 32 caracteres. savepoint_name sempre diferencia maiúsculas de minúsculas, mesmo quando a instância do Mecanismo de Banco de Dados não diferencia maiúsculas de minúsculas.

@savepoint_variable

É o nome de uma variável definida pelo usuário que contém um nome de ponto de salvamento válido. A variável precisa ser declarada com o tipo de dados char, varchar, nchar ou nvarchar. Mais de 32 caracteres podem ser passados para a variável, mas apenas os primeiros 32 caracteres são usados.

Remarks

Você pode definir um ponto de salvamento em uma transação. O ponto de salvamento define um estado de consistência ao qual uma transação pode retornar se uma parte da transação for cancelada condicionalmente. Se uma transação for revertida para um ponto de salvamento, ela deverá prosseguir para a conclusão com mais instruções Transact-SQL, se necessário e uma COMMIT TRANSACTION instrução, ou deve ser cancelada completamente revertendo a transação de volta ao seu início. Para cancelar uma transação inteira, use o formulário ROLLBACK TRANSACTION transaction_name. Todas as instruções ou procedimentos da transação são desfeitos.

Nomes de ponto de salvamento duplicados são permitidos em uma transação, mas uma ROLLBACK TRANSACTION instrução que especifica o nome do ponto de salvamento só reverte a transação para o mais recente SAVE TRANSACTION usando esse nome.

SAVE TRANSACTION não há suporte em transações distribuídas iniciadas explicitamente com BEGIN DISTRIBUTED TRANSACTION ou promovidas de uma transação local.

Observação

O Mecanismo de Banco de Dados não dá suporte a transações aninhadas gerenciáveis de forma independente. Uma confirmação de uma transação interna diminui @@TRANCOUNT , mas não tem outros efeitos. Uma reversão de uma transação interna sempre reverte a transação externa, a menos que um ponto de salvamento exista e seja especificado na instrução ROLLBACK .

Comportamento de bloqueio

Uma ROLLBACK TRANSACTION instrução que especifica um savepoint_name libera todos os bloqueios adquiridos além do ponto de salvamento, exceto para bloqueios escalonados e convertidos. Esses bloqueios não são liberados e não são convertidos de volta para o modo de bloqueio anterior.

Permissions

Exige a associação à função public.

Examples

Os exemplos de código neste artigo usam o banco de dados de exemplo AdventureWorks2025 ou AdventureWorksDW2025, que você pode baixar na página inicial Microsoft SQL Server Samples and Community Projects.

O exemplo a seguir mostra como usar um ponto de salvamento de transação para reverter apenas as modificações feitas por um procedimento armazenado se uma transação for iniciada antes que o procedimento armazenado seja executado.

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