Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Le nombre de transactions après EXECUTE indique un nombre non concordant d'instructions BEGIN et COMMIT. Compte précédent =1, compte actuel =0

Si vous avez un bloc TRY/CATCH, la cause probable est que vous interceptez une exception d'abandon de transaction et que vous continuez. Dans le bloc CATCH, vous devez toujours vérifier le XACT_STATE() et gérer les transactions avortées et non engageables (condamnées) appropriées. Si votre appelant démarre une transaction et que le calee rencontre, par exemple, une impasse (qui a interrompu la transaction), comment l'appelé va-t-il communiquer à l'appelant que la transaction a été interrompue et qu'elle ne devrait pas continuer avec le "business as usual" ? Le seul moyen possible est de relancer une exception, forçant l'appelant à gérer la situation. Si vous avalez silencieusement une transaction abandonnée et que l'appelant continue en supposant qu'il est toujours dans la transaction d'origine, seul le chaos peut garantir (et l'erreur que vous obtenez est la façon dont le moteur essaie de se protéger).

Je vous recommande d'aller sur Gestion des exceptions et transactions imbriquées qui montre un modèle qui peut être utilisé avec des transactions imbriquées et des exceptions :

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
go