Reputation: 2201
I need to execute a store procedure from another with the common EXEC
command.
I need to be sure, that all the sql statements will be under transaction.
BEGIN TRANSACTION
BEGIN TRY
SET @Esercizio = (SELECT ESERCIZIO_OBIETTIVI_CONSUNTIVARE from TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE)
SET @TipoProcesso = (SELECT ISNULL(TipoProcesso, 'middle') from TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE)
DELETE FROM TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE
DELETE FROM TB_SCHEDE_AUTOVAL WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE
DELETE FROM TB_OBIETTIVI WHERE MATRICOLA = @iMATRICOLA and ESERCIZIO = @Esercizio
DELETE FROM TB_OBIETTIVI_AUTOVAL WHERE MATRICOLA = @iMATRICOLA and ESERCIZIO = @Esercizio
EXEC AnotherStore @iCOD_VALUTAZIONE, @iMATRICOLA, @TipoProcesso
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
If the AnotherStore
procedure throw an exception, does the DB engine ensure rollback from the caller store procedure?
Hope to be clear.
Upvotes: 7
Views: 11285
Reputation: 1610
The simple answer is yes it will rollback the changes for the caller stored procedure, but think it through if you have transactions inside the other stored procedure, there are possibilities for things not behaving as you expect if that is the case. A ROLLBACK
will affect ALL of the transactions, although this is probably what you want. You can use @@TRANCOUNT
within your catch and determine if you want to rollback the entire thing, and Savepoints.
Everything you do to the database between the BEGIN TRANSACTION
and COMMIT
or ROLLBACK
is part of the transaction, and if any lines get an error, control will be routed to the CATCH
block where the transaction will be rolled back. Things like table variables would fall outside of this scope and not get rolled back. And as @David Brabant said, BEGIN TRANSACTION
should be in the BEGIN TRY
block.
Upvotes: 2
Reputation: 294387
See Exception handling and nested transactions for an example of execption handling in the presence of transactions:
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
Upvotes: 2