Het is mogelijk dat het werk van SP2 wordt teruggedraaid en het werk van SP1 niet verliest. Maar om dit te laten gebeuren, moet u uw opgeslagen procedures schrijven met een heel specifiek patroon, zoals beschreven in Afhandeling van uitzonderingen en geneste transacties :
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
Niet alle fouten kunnen worden hersteld, er zijn een aantal foutcondities waarvan een transactie niet kan worden hersteld, het meest voor de hand liggende voorbeeld is een deadlock (u wordt op de hoogte gebracht van de deadlock-uitzondering na de transactie is al teruggedraaid). Zowel SP1 als [email protected]
moeten worden geschreven met behulp van dit patroon. Als je een malafide SP hebt, of als je eenvoudig gebruik wilt maken van bestaande opgeslagen procedures die je zonder enige moeite ROLLBACK
geven verklaringen, dan is je zaak verloren.