【问题标题】:Don't rollback the transaction on error in Entity Framework不要回滚实体框架中的错误事务
【发布时间】:2015-08-25 08:39:28
【问题描述】:

当 Entity Framework 操作中发生错误时,任何环境事务都会中止,我无法将其用于更多数据库工作。例如,一旦我尝试打开嵌套事务范围,它就会抛出 TransactionAbortedException 说“事务已中止”。

当我预计会出现错误并知道如何继续时,我可以做些什么来防止这种情况发生?

using (var scope = new TransactionScope())
{
    using (var ctx = new MyContext())
    {
        try
        {
            var x = ctx.MyEntities.FirstOrDefault();
        }
        catch
        {
            CreateTable();
            // Custom DDL command. I can't use EF migrations.
            // Should that fail or not help, I'm happy to see more exceptions later.
        }
        // TODO: Transaction scope is already aborted!
        ctx.MyEntities.Add(...);
    }
    scope.Complete();
}

如果有帮助,我可以创建一个新的 DbContext 实例。

【问题讨论】:

    标签: .net entity-framework transactions


    【解决方案1】:

    SQL Server 没有记录什么样的异常会回滚事务。你不能让它不回滚,坦率地说这是愚蠢的,而且没有技术原因。它也很容易在出错的情况下继续执行(然后没有事务)。此外,很难预测哪些错误会回滚,哪些不会。

    事务没有被 EF 回滚。 SQL Server 会这样做。

    您可能可以执行带有异常处理的原始 SQL:

    TRY
     YourStatementHere
    END TRY
    CATCH
    ...
    

    应该保持交易有效。

    【讨论】:

    • 我在实体框架中,使用映射查询。此外,这应该适用于多个数据库。 (实际上我是先用 SQL Server 测试的,但我没有提到它。)这里不能选择高度定制的 SQL。在这种情况下,预计会出现“表不存在”类型的错误,因此 CreateTable 调用作为处理错误的措施。 +1 表示数据库服务器已经中止事务,而不是 EF。
    • 那么你运气不好......也许你可以启动一个不同的连接+事务对并在那里进行检查。您的主要 tran 将生效。
    • 就是这样,另一个带有Suppress 选项的TransactionScope 成功了。我需要从事务中删除可能失败的命令。由于它可能返回过时的数据,如果没有错误,我必须在事务中重复它并使用该结果。
    • 好的。另一个警告:EF 为每个查询打开一个新连接。这会导致升级到 MSDTC。在您的计算机上禁用 MSDTC 以发现此类问题。
    • 我没有观察到任何与分布式事务相关的问题,MSDTC 服务也停止了。只使用一个数据库。此外,关于 SQL Server,根据我的阅读,这应该在 7 年前用 SQL Server 2008 修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多