【问题标题】:Cannot rollback transaction with Entity Framework无法使用实体框架回滚事务
【发布时间】:2010-12-17 00:11:41
【问题描述】:

我必须对未提交的更改进行查询,我尝试使用事务,但我发现如果有异常它不起作用。

我做了一个简单的例子来重现这个问题。 我有一个数据库,只有一个名为“Tabella”的表,该表有两个字段:“ID”是自动生成的整数,“Valore”是具有唯一约束的整数。然后我尝试运行这段代码:

using (TransactionScope scope = new TransactionScope())
{
    Db1Container db1 = new Db1Container();

    try
    {
        db1.AddToTabella(new Tabella()
        {
            Valore = 1
        });
        db1.SaveChanges();
    }
    catch { }

    try
    {
        db1.AddToTabella(new Tabella()
        {
            Valore = 1
        });
        db1.SaveChanges(); //Unique constraint is violated here and an exception is thrown
    }
    catch { }

    try
    {
        db1.AddToTabella(new Tabella()
        {
            Valore = 2
        });
        db1.SaveChanges();
    }
    catch { }

    //scope.Complete(); //NEVER called
}   //here everything should be rolled back

现在,如果我查看数据库,它应该不包含任何记录,因为事务应该回滚,而是找到两条记录!!!!一个 Valore=1,一个 Valore=2。 我错过了什么?看起来对 SaveChanges 方法的第二次调用回滚了它自己的更改并“删除”了事务,然后对 SaveChanges 的第三次调用提交了第一次和第三次插入的更改(此时就像事务不存在一样)。

我也尝试使用 SaveChanges(false) 方法(即使没有调用 AcceptAllChanges 方法),但没有成功:我有同样的行为。

我不希望事务被 SaveChanges 自动回滚,因为我想纠正错误(例如通过用户交互在 catch 语句中)并重试。

有人可以帮我解决这个问题吗?好像是个“bug”,真是让我头疼啊……

【问题讨论】:

  • 奇怪的行为...你确定你的代码吗?还要考虑通常 Db1Container 也应该关闭/处置。
  • 我投票决定将此问题作为题外话结束,因为它 (1) 是由无法再复制的问题引起的,(2) 上次活跃的提问者没有回应2010, (3) 没有公认或有用的答案。

标签: c# entity-framework transactions rollback


【解决方案1】:

您确定永远不会调用 scope.Complete() 吗?如果catch{}所有异常,代码将继续运行并到达 Complete 语句。相反,您应该让异常传播并在更高级别捕获它。

【讨论】:

    【解决方案2】:

    这对于最初的问题来说有点晚了,但也许它会对某人有所帮助。

    此代码应适用于 .net/ef 4 和 sql server 2008 R2。

    using (TransactionScope scope = new TransactionScope())
    {
        Db1Container db1 = new Db1Container();
    
        try
        {
            db1.AddToTabella(new Tabella()
            {
                Valore = 1
            });
            db1.SaveChanges();
    
            db1.AddToTabella(new Tabella()
            {
                Valore = 1
            });
            db1.SaveChanges(); //Unique constraint is violated here and an exception is thrown
    
            //if we get here then there were no errors thrown on previous SaveChanges() 
            //calls and we can complete the transaction with no rollback
            scope.Complete();
    
        }
        catch (Exception)
        {
            //do nothing
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-13
      相关资源
      最近更新 更多