Thursday, March 3, 2011

LINQ to Entity Gotcha : Transaction rollback

Another cool nugget from the book : Programming Microsoft LINQ in Microsoft .NET Framework 4

What happens if you call SaveChanges() and a transaction that continues beyond the SaveChanges call gets aborted?

  • The good: Internally the same transaction is used by the DbConnection. This means all data DB modifications are rolled back.
  • The bad: The EntityState objects managed by the ObjectStateManager  are all set to Modified and are not reverted. These in-memory operations are not protected by the transaction! This means that you will not be able to call SaveChanges again for this particular set of changes. 
So how do you get around this?

Two steps:

  • You need to call an overload of objectContext.SaveChanges providing the SaveOptions enumeration of either SaveOptions.DetectChangesBeforeSave or SaveOptions.None. You cannot use SaveOptions.AcceptAllChangesAfterSave.
  • If the transaction is successful call objectContext.AcceptAllChanges(); after the transaction.