Maison >base de données >tutoriel mysql >Comment corriger les erreurs « Le nombre de transactions après EXECUTE indique un nombre incompatible d'instructions BEGIN et COMMIT » dans les procédures stockées ?

Comment corriger les erreurs « Le nombre de transactions après EXECUTE indique un nombre incompatible d'instructions BEGIN et COMMIT » dans les procédures stockées ?

DDD
DDDoriginal
2025-01-04 22:41:41376parcourir

How to Fix

Comptes BEGIN-COMMIT incompatibles : erreur de nombre de transactions

Dans un scénario où une procédure stockée appelle une autre procédure stockée dans une instruction EXECUTE, un une erreur peut se produire si le nombre de transactions ne correspond pas. Le message d'erreur suivant illustre ce problème :

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0

Root Cause

Cette erreur se produit généralement lorsque la procédure stockée de l'appelant démarre une transaction (avec BEGIN) et que l'appelé la procédure stockée ne gère pas correctement la transaction exceptions.

Enquête

Après examen du code, il a été découvert que la procédure stockée de l'appelé ne vérifiait pas les interruptions de transaction ou les transactions non validées dans son bloc TRY/CATCH. . Lorsqu'une exception se produit, la transaction doit être correctement gérée.

Solution

Pour résoudre ce problème, la procédure stockée de l'appelé doit être modifiée pour inclure une gestion appropriée de l'état de la transaction . L'exemple suivant illustre l'approche recommandée :

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

label exit:
        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

Ressources supplémentaires

  • [Gestion des exceptions et ressources imbriquées Transactions](https://docs.microsoft.com/en-us/sql/t-sql/statements/begin-transaction-transact-sql?view=sql-server-ver15#exceptions-and-nested-transactions)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn