Prefiero recomendar un patrón como el de Manejo de excepciones y transacciones anidadas :
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
Este patrón verifica XACT_STATE()
en el bloque catch para evitar transacciones no confirmables :
Transacciones no comprometidas y XACT_STATE
Si un error generado en un bloque TRY hace que se invalide el estado de la transacción actual, la transacción se clasifica como una transacción no confirmable. Un error que normalmente finaliza una transacción fuera de un bloque TRY hace que una transacción entre en un estado no confirmable cuando el error ocurre dentro de un bloque TRY. Una transacción no confirmable solo puede realizar operaciones de lectura o una TRANSACCIÓN ROLLBACK. La transacción no puede ejecutar ninguna instrucción Transact-SQL que genere una operación de escritura o una TRANSACCIÓN DE COMPROMISO. La función XACT_STATE devuelve un valor de -1 si una transacción se ha clasificado como una transacción no confirmable. Cuando finaliza un lote, el Motor de base de datos revierte las transacciones no confirmables activas. Si no se envió un mensaje de error cuando la transacción entró en un estado no confirmable, cuando finalice el lote, se enviará un mensaje de error a la aplicación cliente. Esto indica que se detectó una transacción no confirmada y se revertió.
Su código está buscando @@TRANCOUNT
lugares donde no puede ser 0, utiliza una mezcla de mensajes PRINT informativos y conjuntos de resultados SELECT para comunicar con éxito, no maneja errores que son recuperables. Idealmente, las excepciones deberían propagarse al cliente, en este caso al trabajo del Agente (es decir, su captura debería volver a subir).