EF: How do I call SaveChanges twice inside a transaction?
I know it's kind of late answer but i found it useful to share.
Now in EF6 it's easier to acheeve this by using dbContext.Database.BeginTransaction()
like this :
using (var context = new BloggingContext())
{
using (var dbContextTransaction = context.Database.BeginTransaction())
{
try
{
// do your changes
context.SaveChanges();
// do another changes
context.SaveChanges();
dbContextTransaction.Commit();
}
catch (Exception)
{
dbContextTransaction.Rollback();
}
}
}
for more information look at this
again it's in EF6 Onwards
It is probably caused by two different connections used in your transaction. Try to control connection for your operation manually:
var objectContext = ((IObjectContextAdapter)db).ObjectContext;
try {
//Open Connection
objectContext.Connection.Open();
using (var transaction = new TransactionScope()) {
// Do something
db.SaveChanges();
// Do something else
db.SaveChanges();
transaction.Complete();
}
} finally {
//Close connection after commit
objectContext.Connection.Close();
}
By calling SaveChanges() as you are is causing the data to be persisted to the database and the EF to forget about the changes it just made.
The trick is to use SaveChanges(false) so that the changes are persisted to the DB but EF doesn't forget the changes it makes thus making logging / retrying possible.
var scope = new TransactionScope(
TransactionScopeOption.RequiresNew,
new TransactionOptions() { IsolationLevel = IsolationLevel.Serializable }
);
using (scope)
{
Entities context1 = new Entities();
// Do Stuff
context1.SaveChanges(false);
Entities context2 = new Entities();
// Do Stuff
context2.SaveChanges(false);
scope.Complete();
context1.AcceptAllChanges();
context2.AcceptAllChanges();
}
P.S. As soon as you have more than one connection open inside transactionscope it WILL escalate to DTC.