sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server - Indlejrede transaktioner i en lagret procedure

Det er muligt for SP2's arbejde at blive rullet tilbage og ikke miste arbejdet udført af SP1. Men for at dette kan ske, skal du skrive dine lagrede procedurer ved hjælp af et meget specifikt mønster, som beskrevet i Undtagelseshåndtering og indlejrede transaktioner :

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

Ikke alle fejl kan gendannes, der er en række fejltilstande, som en transaktion ikke kan genoprette fra, det mest oplagte eksempel er deadlock (du får besked om deadlock-undtagelsen efter transaktionen er allerede rullet tilbage). Både SP1 og [email protected] skal skrives ved hjælp af dette mønster. Hvis du har en slyngel SP, eller du blot ønsker at udnytte eksisterende lagrede procedurer, som uvildigt udløser ROLLBACK udsagn, så er din sag tabt.



  1. Uddrag 1. tre oktetter af en IPV4

  2. Hvad er en god praksis/design til at tråde flere SQL-forespørgsler i Python

  3. Får duplikatkolonnenavnsfejl i Django uden nogen åbenbar grund

  4. MySQL-valgsforespørgsel med variabel kolonnenavn