Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

SQL Server - Transactions imbriquées dans une procédure stockée

Il est possible que le travail effectué par SP2 soit annulé et ne perde pas le travail effectué par SP1. Mais pour que cela se produise, vous devez écrire vos procédures stockées en utilisant un modèle très spécifique, comme décrit dans Gestion des exceptions et transactions imbriquées :

create procedure [usp_my_procedure_name]
as
begin
    set nocount on;
    declare @trancount int;
    set @trancount = @@trancount;
    begin try
        if @trancount = 0
            begin transaction
        else
            save transaction usp_my_procedure_name;

        -- Do the actual work here

lbexit:
        if @trancount = 0   
            commit;
    end try
    begin catch
        declare @error int, @message varchar(4000), @xstate int;
        select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
        if @xstate = -1
            rollback;
        if @xstate = 1 and @trancount = 0
            rollback
        if @xstate = 1 and @trancount > 0
            rollback transaction usp_my_procedure_name;

        raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
    end catch   
end

Toutes les erreurs ne sont pas récupérables, il existe un certain nombre de conditions d'erreur qu'une transaction ne peut pas récupérer, l'exemple le plus évident étant le blocage (vous êtes informé de l'exception de blocage après la transaction a déjà été annulée). SP1 et [email protected] doivent être écrits en utilisant ce modèle. Si vous avez un SP non autorisé ou si vous souhaitez simplement tirer parti des procédures stockées existantes qui émettent à la légère ROLLBACK déclarations, votre cause est perdue.