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.