53

I would like know what is the best possible way to implement transactions with DBContext. In particular,

  1. Does DbContext.SaveChanges implement transaction internall if i change multiple entities?
  2. If i want to call DbContext.SaveChanges multiple times(same contxet/different contxets), how transaction can be achieved?
Scotty.NET
  • 12,533
  • 4
  • 42
  • 51
user396491
  • 941
  • 2
  • 12
  • 12

2 Answers2

76
  1. Yes. SaveChanges uses transaction internally.
  2. Use TransactionScope to wrap multiple calls to SaveChanges

Example:

using(var scope = new TransactionScope(TransactionScopeOption.Required,
    new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
{
    // Do something 
    context.SaveChanges();
    // Do something else
    context.SaveChanges();

    scope.Complete();
}
Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • 6
    Be sure to be using Sql 2008 or later as the database (or have the MSDTC service running on the client). Previous versions will escalate the transaction to a distributed transaction on the second `SaveChanges`. This is due to how `DbContext` internally handles the opening and closing of its connection. – Lukazoid Jan 19 '12 at 15:51
  • Is is possible to get an identity from the first save changes? I always see Id = 0. – JarrettV Jan 24 '12 at 17:11
  • @JarrettV - I think your issue is because of the IsolationLevel settings. Lowering it might help... – Sunny Mar 12 '12 at 17:00
  • This wont work with EF 4.3.1. We will have to open the connection on the Objectcontext explicitly before we call context.SaveChanges(). – renegadeMind Apr 27 '12 at 17:00
  • @renegadeMind: Of course this will work with DbContext. What you describe is advanced way used when you want to avoid distributed transaction. – Ladislav Mrnka Apr 27 '12 at 18:17
  • @LadislavMrnka Yes you are correct; but don't we want to avoid DTC by default? I assumed that we do and hence my answer! – renegadeMind May 01 '12 at 20:59
0

For asynchronous operation do the following.

using(var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    // Do something 
    await context.SaveChangesAsync();
    // Do something else
    await context.SaveChangesAsync();

    scope.Complete();
}

References: learn.microsoft.com/en-us/ef/ef6/saving/transactions

Lakshitha Kanchana
  • 844
  • 2
  • 12
  • 32