如何在Entity Framework中回滚事务

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

也许这是自动完成的,意思是如果出现错误,所有更改都将被取消提交。是吗?
2个回答

12

好的

我创建了一个示例应用程序,类似于问题中的示例,然后检查了数据库,发现没有添加用户。

结论:ObjectContext.SaveChange自动成为事务。

注意:如果执行存储过程等操作,则需要使用事务。


8
我认为(但我不是EF的长期专家),在调用context.SaveChanges之前,事务尚未启动。我期望从该调用中抛出的异常会自动回滚它启动的任何事务。 替代方案(如果您想控制事务)[来自J.Lerman的“Programming Entity Framework” O'Reilly,第618页]
using (var transaction = new System.Transactions.TransactionScope())
{
  try
  {
    context.SaveChanges();
    transaction.Complete();
    context.AcceptAllChanges();
  }
  catch(OptimisticConcurrencyException e)
  {
    //Handle the exception
    context.SaveChanges();
  }
}

或者

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();
    }
  }

}

本质上,我认为在简单场景中,您可以免费获得事务回滚,并且对于更复杂的情况,您需要像这两个示例所示的那样处理事务。您的示例应用程序似乎证实了这一点。 如果我的措辞不太好,请谅解 - 昨天写这篇文章时我正在开会。 - FOR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接