É possível que o trabalho feito pelo SP2 seja revertido e não perca o trabalho feito pelo SP1. Mas para que isso aconteça, você deve escrever seus procedimentos armazenados usando um padrão muito específico, conforme descrito em Tratamento de exceção e transações aninhadas :
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
Nem todos os erros são recuperáveis, existem várias condições de erro das quais uma transação não pode se recuperar, sendo o exemplo mais óbvio o deadlock (você é notificado da exceção de deadlock depois a transação já foi revertida). Ambos SP1 e [email protected] devem ser escritos usando este padrão. Se você tem um SP desonesto, ou quer simplesmente aproveitar os procedimentos armazenados existentes que emitem
ROLLBACK
sem querer declarações, então sua causa está perdida.