string[] usersToAdd = new string[] { "asd", "asdert", "gasdff6" };
using (Entities context = new Entities())
{
foreach (string user in usersToAdd)
{
context.AddToUsers(new User { Name = user });
}
try
{
context.SaveChanges(); //Exception thrown: user 'gasdff6' already exist.
}
catch (Exception e)
{
//Roll back all changes including the two previous users.
}
Or maybe this is done automatically, meaning that if error occurs, committing changes are canceled for all the changes. is it?
A DbContextTransaction object provides Commit() and Rollback() methods to do commit and rollback on the underlying store transaction. This method requires an open underlying stored connection. This method opens a connection if it is not already open. This method will close the connection when Dispose () is called.
In Entity Framework, the SaveChanges() method internally creates a transaction and wraps all INSERT, UPDATE and DELETE operations under it. Multiple SaveChanges() calls, create separate transactions, perform CRUD operations and then commit each transaction. The following example demonstrates this.
In all versions of Entity Framework, whenever you execute SaveChanges() to insert, update or delete on the database the framework will wrap that operation in a transaction. This transaction lasts only long enough to execute the operation and then completes.
OK
I created a sample a application like the example from the the question and afterwords I checked in the DB and no users were added.
Conclusion: ObjectContext.SaveChange it's automatically a transaction.
Note: I believe transactions will be needed if executing sprocs etc.
I believe (but I am no long time expert in EF) that until the call to context.SaveChanges goes through, the transaction is not started. I'd expect an Exception from that call would automatically rollback any transaction it started. Alternatives (in case you want to be in control of the transaction) [from J.Lerman's "Programming Entity Framework" O'Reilly, pg. 618]
using (var transaction = new System.Transactions.TransactionScope())
{
try
{
context.SaveChanges();
transaction.Complete();
context.AcceptAllChanges();
}
catch(OptimisticConcurrencyException e)
{
//Handle the exception
context.SaveChanges();
}
}
or
bool saved = false;
using (var transaction = new System.Transactions.TransactionScope())
{
try
{
context.SaveChanges();
saved = true;
}
catch(OptimisticConcurrencyException e)
{
//Handle the exception
context.SaveChanges();
}
finally
{
if(saved)
{
transaction.Complete();
context.AcceptAllChanges();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With