none
TransactionScope et DbContext RRS feed

  • Question

  • Bonjour, 

    J'essaie actuellement de creer une transaction à l'aide de transactionScope dans laquelle plusieurs saveChanges() seront appliqués avec un ou plusieurs context.

    Pour mes test j'ai essayé de me concentrer uniquement sur un context et deux savechanges() seulement je n'arrive pas à faire fonctionner correctement la transaction.

    Voici mon code :

            public bool addProduit_withColl(ObjProduit aProduit)
            {
                // define our transaction scope
                DataPg.ModelContext context = new DataPg.ModelContext();
                var scopeMain = new TransactionScope(TransactionScopeOption.RequiresNew, new TimeSpan(00,00,30));
     
                bool Success = true;
                int nb = 0;
                //Generation de la clé primaire
                aProduit.id = Guid.NewGuid().ToString("N").ToUpper();
     
                try
                {
                    using (scopeMain)
                    {
                        //Step 1 - Add Produit
                        context.produit.Add(aProduit);
                        nb = context.SaveChanges();
     
                        //Step 2 - Add collection of produit
                        foreach (ImgProduit aImg in aProduit.collImg)
                        {
                            //Generation de la clé primaire
                            aImg.id = Guid.NewGuid().ToString("N").ToUpper();
                            aImg.id_produit = aProduit.id;
                            context.imgproduit.Add(aImg);
     
                            nb = context.SaveChanges();
                        }
     
                        //if not exception
                        scopeMain.Complete();
                        //((IObjectContextAdapter)context).ObjectContext.AcceptAllChanges();
                    }
                }
                catch(Exception er)
                { 
                    //Transaction.Current.Rollback(); 
                    scopeMain.Dispose();
                    Success = false;
                }
     
                return Success;
            }
    Lorsque je provoque une erreur et que j'appel la méthode dispose() dans mon try catch aucun rollback n'est effectué !

    De plus lorsque je regarde ma base de données avant d'arrivé à la méthode complete() j'arrive à voir le produit ajouté alors que ma requete est en niveau d'isolation serializable et la transaction aussi !

    En essayant de forcer le rollback via la méthode Transaction.Current.Rollback(), une erreur est apparue car la propriété Current à pour valeur null !
    Je ne croit pas que cela soit normal ?!

    Pour info, la base de données est une base PostgreSQL et j'utilise la dll Npgsql.

    J'ai également essayé d'effectuer la transaction avec SaveOptions.DetectChangesBeforeSave et en effectuant un AcceptAllChanges() après la méthode complète mais le comportement est exactement le même !

    Que puis je faire pour m'assurer que la transaction est bien le comportement suivant :
    . Validation des données qu'une fois après la méthode complete() soit appelé
    . RollBack des données en cas d'erreur

    Merci d'avance pour votre aide

    mardi 14 mai 2013 07:32

Réponses

  • J'ai résolu le mystère de la propritété Transaction.Current = null !

    Le try catch étant au dessus de mon bloc using j'etais déjà sortie de ma transaction.

    J'ai donc déplacer le try catch à l'intérieur de l'using, je n'ai plus d'erreur sur la méthode Rollback() et pourtant le produit est quand même enregistré et n'est jamais annulé !

    Il est également visible toujours dans la base de données avant la méthode complete().
    • Marqué comme réponse Aurel Bera mercredi 15 mai 2013 09:27
    mardi 14 mai 2013 07:56
  • J'ai trouvé pourquoi ma méthode ne fonctionne pas et ne fonctionnera pas !

    J'ai oublié de vous préciser un détail. J'utilise cette méthode dans un web service et après de multiple recherche j'ai pu constater que je devais activer des propriétés particulière pour utiliser transactionscope dans un web service et cela m'obliger à avoir la propriété concurrencymode à single au lieu de multiple !

    Par conséquent, je ne peux pas utiliser cette fonction car j'ai absolument besoin la configuration en "multiple" dans mon web service.

    Je sais que ces explication sort un peu du thème du forum "Linq et Entity Framework" mais bon... si sa peut servir à quelqu'un d'autre on sait jamais.

    Si le sujet intéresse quelqu'un voici les liens dans lequel vous pourrez trouver des explications : 

    http://www.123aspx.com/redir.aspx?res=35892

    http://www.codeproject.com/Articles/...actions-in-WCF

    • Marqué comme réponse Kiwi19 jeudi 16 mai 2013 09:17
    jeudi 16 mai 2013 09:17

Toutes les réponses