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

C# Discussion :

TransactionScope et transaction sous SQL Server 2005


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut TransactionScope et transaction sous SQL Server 2005
    Bonjour,

    j'ai développé une WebMethod qui utilise une transaction:

    Code c# : 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
     
    using (TransactionScope scope = new TransactionScope())
    {
    	SqlConnection connection = null;
    	SqlCommand command = null;
     
    	[..] // Traitement
     
    	try
    	{
    		// Appel d'une procédure stockée utilisant une transaction
    		command.ExecuteNonQuery();
    	}
    	catch (Exception ex)
    	{
    		log.Error(ex.Message);		
    		throw new Exception("Erreur de sauvegarde dans la base de données.", ex);
    	}
     
    	trs.Complete();
     
    	[..] // Traitement
    }

    Comme vous le voyez cette WebMethod fait appel à une procédure stockée qui utilise aussi une transaction.
    Cette procédure stockée développée dans une base de données sous SQL Server 2005 est définie ci-dessous:

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE PROCEDURE [dbo].[MyProcedure]
    (
    	-- Liste des paramètres
    )
    AS
     
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRANSACTION MyTransaction
     
    	-- Traitement
     
    COMMIT TRANSACTION MyTransaction

    Il arrive que l'exception avec le message suivant soit lancée par la base de données:

    La transaction distribuée est terminée. Inscrivez cette session, soit dans une nouvelle transaction, soit dans une transaction NULL.
    Que dois-je fais d'après vous pour corriger ce problème ?

    Merci d'avance,
    Zoax

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 109
    Par défaut
    La gestion de ta transaction est faite deux fois : en .Net et dans la procédure stockée.
    Si tu veux gérer ta transaction coté .Net enlève ton

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    BEGIN TRANSACTION MyTransaction
    COMMIT TRANSACTION MyTransaction

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut
    Bonjour,

    et merci pour la réponse.
    Si je retire la gestion de la transaction dans la procédure stockée, comment n'annuler que les modifications effectuées par la procédure si le traitement qu'elle réalise (impliquant plusieurs tables) échoue ?

    Merci d'avance
    ++

  4. #4
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Par défaut
    Mes amis, il ne faut jamais piloter les transactions côté client.
    Il ne faut pas gérer la transaction dans une procédure stockée si vous le fait déjà côté client.

    Faites donc votre choix !

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  5. #5
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut
    Bonjour,

    et merci pour la réponse:

    Mes amis, il ne faut jamais piloter les transactions côté client.
    Il ne faut pas gérer la transaction dans une procédure stockée si vous le fait déjà côté client.
    Pour quelle raison ?

    J'ai manqué de précision dans la description de mon code. J'ai oublié une sauvegarde en base de données, raison pour laquelle j'ai utilisée une transaction dans cette méthode.
    Voici plus exactement la WebMethod que j'ai développée:

    Code c# : 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
     
    using (TransactionScope scope = new TransactionScope())
    {
    	SqlConnection connection = null;
    	SqlCommand command = null;
     
    	[..] // Traitement
     
    	try
    	{
    		// Appel d'une 1ère procédure stockée sauvegardant des données en base de données.
                    // Cette procédure n'utilise pas de transaction
    		command.ExecuteNonQuery();
    	}
    	catch (Exception ex)
    	{
    		log.Error(ex.Message);		
    		throw new Exception("Erreur de sauvegarde dans la base de données.", ex);
    	}
     
    	[..] // Traitement
     
    	try
    	{
    		// Appel d'une 2ème procédure stockée sauvegardant des données en base de données
                    // Cette procédure utilise une transaction
    		command.ExecuteNonQuery();
    	}
    	catch (Exception ex)
    	{
    		log.Error(ex.Message);		
    		throw new Exception("Erreur de sauvegarde dans la base de données.", ex);
    	}
     
    	trs.Complete();
     
    	[..] // Traitement
    }

    J'ai utilisée une transaction dans cette WebMethod pour qu'en cas d'échec pouvoir revenir à l'état initial à tout moment. Par exemple, si la sauvegarde des données en base de données échoue lors de l'appel de la deuxième procédure, les données avant l'appel de la première procédure doivent être restaurée dans la base de données.

    J'ai ensuite utilisée une transaction dans la deuxième procédure pour qu'en cas d'échec du traitement réalisé (modifiant plusieurs tables), l'état initial soit restauré.

    Merci d'avance pour votre aide.
    ++

  6. #6
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Par défaut
    Désolé, j'étais en vancance de fin d'année.
    Citation Envoyé par zoaax Voir le message
    Bonjour,
    Pour quelle raison ?
    Qu'est ce qui se passe si votre poste client s'arrête avant de valider la transaction ?
    La réponse est : Et probablement un plantage des processus qui attendent la libération des ressources immobilisées par ta transactionscope.

    Citation Envoyé par zoaax Voir le message
    Bonjour,
    Code c# : 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
     
    using (TransactionScope scope = new TransactionScope())
    {
    	SqlConnection connection = null;
    	SqlCommand command = null;
     
    	[..] // Traitement
     
    	try
    	{
    		// Appel d'une 1ère procédure stockée sauvegardant des données en base de données.
                    // Cette procédure n'utilise pas de transaction
    		command.ExecuteNonQuery();
    	}
    	catch (Exception ex)
    	{
    		log.Error(ex.Message);		
    		throw new Exception("Erreur de sauvegarde dans la base de données.", ex);
    	}
     
    	[..] // Traitement
     
    	try
    	{
    		// Appel d'une 2ème procédure stockée sauvegardant des données en base de données
                    // Cette procédure utilise une transaction
    		command.ExecuteNonQuery();
    	}
    	catch (Exception ex)
    	{
    		log.Error(ex.Message);		
    		throw new Exception("Erreur de sauvegarde dans la base de données.", ex);
    	}
     
    	trs.Complete();
     
    	[..] // Traitement
    }
    C'est la transactionscope qu'il faut éliminer plutôt que supprimer les transaction dans la SP.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE PROCEDURE PROCGENERAL
    AS
    BEGIN TRANSACTION
           EXEC PROC1
           EXEC PROC2
    COMMIT
    Bien sûr qu'il ne s'agit là que d'un model.

    Il ne vous restera que jouer cette SP depuis un code client C#

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

  7. #7
    Membre émérite
    Avatar de shwin
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    568
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2003
    Messages : 568
    Par défaut
    Citation Envoyé par WOLO Laurent Voir le message
    Mes amis, il ne faut jamais piloter les transactions côté client.
    Tu peux m'expliquer ? Si jai une méthode client qui créé un fichier et qui appel le serveur pour faire une mise a jours dans la DB. Je vais forcément utiliser la transactionScope coté client

    Citation Envoyé par zoaax Voir le message
    J'ai utilisée une transaction dans cette WebMethod pour qu'en cas d'échec pouvoir revenir à l'état initial à tout moment. Par exemple, si la sauvegarde des données en base de données échoue lors de l'appel de la deuxième procédure, les données avant l'appel de la première procédure doivent être restaurée dans la base de données.

    J'ai ensuite utilisée une transaction dans la deuxième procédure pour qu'en cas d'échec du traitement réalisé (modifiant plusieurs tables), l'état initial soit restauré.
    ++
    Si tu utilise le transactionScope, ne t'occupe pas des transaction dans les SP meme si tu utilise plusieur table. Les modifications ne sont que 'commité' que quand tu va faire Commit() sur le scope.

  8. #8
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut
    Bonjour,

    suite à vos remarques, j'ai supprimé la transaction dans la procédure stockée.
    Malgré ça j'ai encore obtenu le même message d'erreur.

    ++

Discussions similaires

  1. [Requete] probleme de synthaxe sous SQL SERVER 2005
    Par sanosuke dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 14/05/2007, 11h24
  2. Création d'un cube sous Sql Server 2005
    Par Valentino62100 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 16/04/2007, 09h42
  3. Acces concurrentiel sous sql server 2005
    Par Marco77 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 07/02/2007, 15h53
  4. Réponses: 1
    Dernier message: 13/12/2006, 14h18
  5. Importé un fichier excel sous SQL Server 2005
    Par summer91 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 01/05/2006, 10h52

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