366 votes

Entity Framework - l'Utilisation de Transactions ou SaveChanges(faux) et AcceptAllChanges()?

J'ai enquêté sur les transactions et il semble qu'ils prennent soin d'eux-mêmes en EF tant que je passe false de SaveChanges() puis appelez AcceptAllChanges() si il n'y a pas d'erreurs:

SaveChanges(false);
// ...
AcceptAllChanges();

Que faire si quelque chose va mal? n'ai-je pas de rollback ou, dès que ma méthode est hors de portée, l'opération est-elle terminée?

Ce qui arrive à tout indentiy colonnes qui ont été affectées à la moitié de la transaction? Je suppose que si quelqu'un d'autre a ajouté un enregistrement après la mienne avant de la mine a été mauvais alors cela signifie qu'il y aura un manque d'Identité de la valeur.

Est-il une raison pour utiliser la norme TransactionScope de la classe dans mon code?

472voto

Alex James Points 15939

Avec Entity Framework, la plupart du temps SaveChanges() est suffisante. Cela crée une transaction, ou enrôle dans toute ambiante transaction, et prend en charge tous les travaux nécessaires à cette transaction.

Parfois, si l' SaveChanges(false) + AcceptAllChanges() le couplage est utile.

La plus utile au lieu de cela est dans les situations où vous souhaitez effectuer une transaction distribuée dans deux Contextes différents.

I. e. quelque chose comme ceci (mauvais):

using (TransactionScope scope = new TransactionScope())
{
    //Do something with context1
    //Do something with context2

    //Save and discard changes
    context1.SaveChanges();

    //Save and discard changes
    context2.SaveChanges();

    //if we get here things are looking good.
    scope.Complete();
}

Si context1.SaveChanges() réussit, mais context2.SaveChanges() d'échec de l'ensemble de la distributed transaction est annulée. Mais malheureusement, le Cadre de l'Entité a déjà jeté des modifications sur l' context1, de sorte que vous ne pouvez pas rejouer ou efficacement journal de l'échec.

Mais si vous modifiez votre code ressemble à ceci:

using (TransactionScope scope = new TransactionScope())
{
    //Do something with context1
    //Do something with context2

    //Save Changes but don't discard yet
    context1.SaveChanges(false);

    //Save Changes but don't discard yet
    context2.SaveChanges(false);

    //if we get here things are looking good.
    scope.Complete();
    context1.AcceptAllChanges();
    context2.AcceptAllChanges();

}

Alors que l'appel à l' SaveChanges(false) envoie les commandes nécessaires à la base de données, le contexte lui-même n'est pas modifié, de sorte que vous pouvez le faire à nouveau si nécessaire, ou vous pouvez interroger l' ObjectStateManager si vous le souhaitez.

Cela signifie que si l'opération s'interrompt, vous pouvez compenser, re-essayer ou l'enregistrement de l'état de chacun des contextes ObjectStateManager quelque part.

Voir mon blog pour plus d'.

126voto

user3885816 Points 21

Si vous utilisez EF6 (Entity Framework 6+), ce qui a changé pour les appels de base de données SQL.
Voir: http://msdn.microsoft.com/en-us/data/dn456843.aspx

        use context.Database.BeginTransaction.

        using (var context = new BloggingContext()) 
        { 
            using (var dbContextTransaction = context.Database.BeginTransaction()) 
            { 
                try 
                { 
                    context.Database.ExecuteSqlCommand( 
                        @"UPDATE Blogs SET Rating = 5" + 
                            " WHERE Name LIKE '%Entity Framework%'" 
                        ); 

                    var query = context.Posts.Where(p => p.Blog.Rating >= 5); 
                    foreach (var post in query) 
                    { 
                        post.Title += "[Cool Blog]"; 
                    } 

                    context.SaveChanges(); 

                    dbContextTransaction.Commit(); 
                } 
                catch (Exception) 
                { 
                    dbContextTransaction.Rollback(); 
                } 
            } 
        } 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X