IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MS SQL Server Discussion :

problème avec le ROLLBACK TRAN dans une transaction imbriquée


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mars 2007
    Messages : 616
    Par défaut problème avec le ROLLBACK TRAN dans une transaction imbriquée
    J'ai un souci avec un rollback imbriqué.

    Je ne comprends pas pourquoi on n'arrive pas à rollbacker la dernière transaction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'TRANTEST'))
    	DROP PROCEDURE TRANTEST
    GO
     
    CREATE PROCEDURE TRANTEST
    AS
    DECLARE
    	@tran_name VARCHAR(30)
     
    SELECT @tran_name = 'TTest'
     
    BEGIN TRY
    	print @@trancount
    	print 'BEGIN TRAN '+ @tran_name
    		BEGIN TRAN @tran_name 
    	print @@trancount
     
    --select 1/0
     
    		PRINT 'PROCEDURE OK'
     
    	print @@trancount
    	print 'COMMIT TRAN '+ @tran_name
    		COMMIT TRAN @tran_name
    	print @@trancount
    END TRY 
    BEGIN CATCH
    	print @@trancount
    	print 'ROLLBACK TRAN '+ @tran_name
     
    		ROLLBACK TRAN @tran_name
    	print @@trancount
    END CATCH
    GO
    print '-- test 1'
    print @@trancount
    EXECUTE TRANTEST 
    print @@trancount
    GO
     
     
    print '-- test 2'
    print @@trancount
    print 'begin tran toto'
    begin tran toto
    	print @@trancount
    	EXECUTE TRANTEST 
    	print @@trancount
     
    print 'commit tran toto'
    commit tran toto
    print @@trancount
    GO
    et voilà ce que j'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    -- test 1
    0
    0
    BEGIN TRAN TTest
    1
    PROCEDURE OK
    1
    COMMIT TRAN TTest
    0
    0
    -- test 2
    0
    begin tran toto
    1
    1
    BEGIN TRAN TTest
    2
    PROCEDURE OK
    2
    COMMIT TRAN TTest
    1
    1
    commit tran toto
    0
    donc tout va bien les 2 transactions s'imbriquent et committent toutes les 2.
    Si je décommente la ligne --select 1/0, voilà ce que j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    -- test 1
    0
    0
    BEGIN TRAN TTest
    1
     
    (0 row(s) affected)
    1
    ROLLBACK TRAN TTest
    0
    0
    -- test 2
    0
    begin tran toto
    1
    1
    BEGIN TRAN TTest
    2
     
    (0 row(s) affected)
    2
    ROLLBACK TRAN TTest
    Msg 6401, Level 16, State 1, Procedure TRANTEST, Line 28
    Cannot roll back TTest. No transaction or savepoint of that name was found.
    2
    Msg 266, Level 16, State 2, Procedure TRANTEST, Line 0
    Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 2.
    2
    commit tran toto
    1

    Ça veut dire que lorsque la procédure est exécutée seule elle arrive à rollbacker et si la même procédure est imbriquée dans une autre transaction elle ne peut pas être rollbackée.
    Mais comment ca se fait?

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    Il n'existe JAMAIS qu'une seule transaction. La notion de transaction imbriqué n'existe pas, par définition même. Lisez l'article que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/s...ns-imbriquees/

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mars 2007
    Messages : 616
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Il n'existe JAMAIS qu'une seule transaction. La notion de transaction imbriqué n'existe pas, par définition même. Lisez l'article que j'ai écrit à ce sujet :
    Pourtant on parle bien dans la transactions imbriquées sur MSDN.
    J'ai lu cet article, je ne comprends toujours pas pourquoi Microsoft a fait ça. Dans ce cas là quelle est l'intérêt de nommer les transactions?


    P.S. Il faudrait corriger l'article et mettre ça:
    IF @@trancount = 1 ROLLBACK TRAN
    IF @@trancount > 1 COMMIT TRAN

  4. #4
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 94
    Par défaut
    Bonjour,
    j'ai une procédure stockée qui est gérée en transaction et qui peut etre appellée
    - Soit en standalone
    - Soit par une autre proc qui est aussi gérée en transaction

    Mon label de rollback est donc le suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    PS_ERR:
    	IF @@TRANCOUNT = 1
    		ROLLBACK TRANSACTION
    	IF @@TRANCOUNT > 1
    		COMMIT TRAN
    	RETURN -1
    Le problème est que dans le cas d'un appel en transaction imbriquée, j'ai l'erreur suivant sur le COMMIT:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Msg*3930, Niveau*16, État*1, Procédure*xxx, Ligne*474
    La transaction actuelle ne peut pas être validée et ne prend pas en charge les opérations qui écrivent dans le fichier journal. Restaurez la transaction.
    J'ai fait un test avec des print, et effectivement le COMMIT ne décrémente pas @@TRANCOUNT !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    PS_ERR:
    	print '@@TRANCOUNT = ' + convert(varchar(10),@@TRANCOUNT)
    	IF @@TRANCOUNT = 1
    		ROLLBACK TRANSACTION
    	IF @@TRANCOUNT > 1
    	BEGIN
    		COMMIT TRAN
    		print '@@TRANCOUNT décrémenté = ' + convert(varchar(10),@@TRANCOUNT)
    	END
    	RETURN -1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    @@TRANCOUNT = 2
    Msg*3930, Niveau*16, État*1, Procédure*xxx, Ligne*474
    La transaction actuelle ne peut pas être validée et ne prend pas en charge les opérations qui écrivent dans le fichier journal. Restaurez la transaction.
    @@TRANCOUNT décrémenté = 2
    Pourquoi cela ????

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mars 2007
    Messages : 616
    Par défaut
    Citation Envoyé par chris92 Voir le message
    Bonjour,
    j'ai une procédure stockée qui est gérée en transaction et qui peut etre appellée
    - Soit en standalone
    - Soit par une autre proc qui est aussi gérée en transaction

    Mon label de rollback est donc le suivant:

    J'ai fait un test avec des print, et effectivement le COMMIT ne décrémente pas @@TRANCOUNT !

    Pourquoi cela ????
    Déjà, tu aurais dû créer un autre post.

    Sinon, le problème est dû surement à une transaction non committable, suite a une erreur dans la procédure. Tu as du surement essayé de créer une contrainte que tu violes déjà.
    C'est effectivement un sujet qui n'est pas traité par l'article de SQLPro.

    Lis ces 2 articles XACT_STATE et SET XACT_ABORT.
    Lorsque cet erreur ce produit tu n'a pas d'autres choix que de tout rollbacker et sortir proprement.
    Dans mes procédures j'ai dû faire ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	-- Annulation des transactions
    	IF @@trancount = 1 OR XACT_STATE() = -1 ROLLBACK TRAN
    	IF @@trancount > 1 COMMIT TRAN @step_name
    A+

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 94
    Par défaut
    Justement ce que j'ai pas bien ncompris, c'est que COMMIT ne devrait pas regarder la validité de la transaction si @@TRANCOUNT > 1 !!

    Sinon j'ai résolu mon problème de la façon suivante:

    dans ma proc pouvant être appellée soit en standalone, soit par une autre proc gérant deja une transaction, j'ai le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    SET @IND_GEST_TRAN = 0
     
    IF @@TRANCOUNT = 0
    BEGIN
    	SET @IND_GEST_TRAN = 1
    	BEGIN TRANSACTION
    END
     
    ...
    Exit:
    	IF @IND_GEST_TRAN = 1
    		COMMIT TRANSACTION
     
    ...
    Err:
    	IF @IND_GEST_TRAN = 1
    		ROLLBACK TRANSACTION
    Merci !

Discussions similaires

  1. Problème avec la multi-sélection dans une zone de liste
    Par Mimisio dans le forum VBA Access
    Réponses: 2
    Dernier message: 16/07/2007, 16h23
  2. Problème avec 2 blocs IF dans une procedure
    Par asgard dans le forum Delphi
    Réponses: 14
    Dernier message: 13/01/2007, 03h07
  3. [SQL] Problème avec nombre d'enregistrements dans une table
    Par zana74 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 14/08/2006, 13h28
  4. Problème avec nombre d'enregistrements dans une table
    Par zana74 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 14/08/2006, 13h21
  5. [VB6] Problème avec la touche 0 dans une MaskEdBox
    Par bb62 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 02/03/2006, 09h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo