Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server – Verschachtelte Transaktionen in einer gespeicherten Prozedur

Es ist möglich, dass die von SP2 ausgeführte Arbeit rückgängig gemacht wird und die von SP1 ausgeführte Arbeit nicht verloren geht. Aber damit dies geschieht, müssen Sie Ihre gespeicherten Prozeduren nach einem ganz bestimmten Muster schreiben, wie in Ausnahmebehandlung und verschachtelte Transaktionen :

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

Nicht alle Fehler sind behebbar, es gibt eine Reihe von Fehlerzuständen, von denen eine Transaktion nicht wiederhergestellt werden kann, das offensichtlichste Beispiel ist Deadlock (Sie werden nach über die Deadlock-Ausnahme benachrichtigt die Transaktion wurde bereits rückgängig gemacht). Sowohl SP1 als auch [email protected] müssen nach diesem Muster geschrieben werden. Wenn Sie einen Schurken-SP haben oder einfach vorhandene gespeicherte Prozeduren nutzen möchten, die einfach nur ROLLBACK ausgeben Aussagen, dann ist Ihre Sache verloren.