Как откатить транзакцию в Entity Framework

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.
    }

Или, может быть, это делается автоматически, что означает, что в случае ошибки фиксация изменений отменяется для всех изменений. это?


person Shimmy Weitzhandler    schedule 01.07.2009    source источник


Ответы (2)


OK

Я создал образец приложения, подобный примеру из вопроса и послесловия, который я проверил в БД, и пользователи не были добавлены.

Вывод: ObjectContext.SaveChange автоматически является транзакцией.

Примечание: я считаю, что транзакции потребуются при выполнении sprocs и т. д.

person Shimmy Weitzhandler    schedule 01.07.2009

Я считаю (но я давно не эксперт в EF), что пока вызов context.SaveChanges не пройдет, транзакция не запустится. Я ожидаю, что исключение из этого вызова автоматически отменит любую начатую транзакцию. Альтернативы (на случай, если вы хотите контролировать транзакцию) [из "Programming Entity Framework" Дж. Лермана О'Рейли, стр. 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();
    }
  }

}
person FOR    schedule 01.07.2009
comment
По сути, я считаю, что в простом сценарии вы получаете откат транзакций бесплатно, а для более сложных сценариев вам нужно будет обрабатывать транзакции, как показано в двух примерах. Ваш образец приложения, кажется, подтверждает это. Извините, если моя формулировка была менее чем звездной - это было между встречами, когда я написал это вчера. - person FOR; 02.07.2009