sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server - Kapslade transaktioner i en lagrad procedur

Det är möjligt att det arbete som utförts av SP2 rullas tillbaka och inte förlorar det arbete som utförts av SP1. Men för att detta ska hända måste du skriva dina lagrade procedurer med ett mycket specifikt mönster, som beskrivs i Undantagshantering och kapslade 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

Alla fel kan inte återställas, det finns ett antal feltillstånd som en transaktion inte kan återhämta sig från, det mest uppenbara exemplet är dödläge (du meddelas om undantaget dödläge efter transaktionen har redan återställts). Både SP1 och [email protected] måste skrivas med detta mönster. Om du har en oseriös SP, eller om du enkelt vill utnyttja befintliga lagrade procedurer som helt enkelt ger ROLLBACK uttalanden så är din sak förlorad.



  1. Ajax metod för att fylla i en andra dynamisk rullgardinsmeny baserat på urvalet i den första

  2. Hur partitionerar man Mysql över FLERA SERVRAR?

  3. Noll Data Loss Recovery Appliance

  4. SQL-tabell med listpost vs SQL-tabell med en rad för varje post