ZombieCheck异常 - 此SqlTransaction已完成;它不再可用 - 在简单提交期间

时间:2013-05-22 13:18:11

标签: sql-server transactions

我有以下代码执行将单行提交到数据库表(SQL 2008 / .NET 4)

using (var db = new MyDbDataContext(_dbConnectionString))
{
    Action action = new Action();
    db.Actions.InsertOnSubmit(dbAction);
    db.SubmitChanges();
}

通常一切都很好,但有一段时间我得到以下异常:

System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable.
at System.Data.SqlClient.SqlTransaction.ZombieCheck()
at System.Data.SqlClient.SqlTransaction.Rollback()
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)

在SO上有很多类似的问题,但在阅读之后我无法解决问题。

这可能仅仅是由于SQL超时(在调用之后接近25秒发生异常)?或者在这种情况下我应该期待SQL超时异常吗?

有谁知道还有什么可能导致这种情况?

3 个答案:

答案 0 :(得分:10)

DataContext.SubmitChanges方法在其正文中包含以下代码行:

// ...
try
{
    if (this.provider.Connection.State == ConnectionState.Open)
    {
        this.provider.ClearConnection();
    }
    if (this.provider.Connection.State == ConnectionState.Closed)
    {
        this.provider.Connection.Open();
        flag = true;
    }
    dbTransaction = this.provider.Connection.BeginTransaction(IsolationLevel.ReadCommitted);
    this.provider.Transaction = dbTransaction;
    new ChangeProcessor(this.services, this).SubmitChanges(failureMode);
    this.AcceptChanges();
    this.provider.ClearConnection();
    dbTransaction.Commit();
}
catch
{
    if (dbTransaction != null)
    {
        dbTransaction.Rollback();
    }
    throw;
}
// ...

当连接超时时,catch阻止执行,dbTransaction.Rollback();行将抛出InvalidOperationException

如果您可以控制代码,则可以捕获这样的异常:

catch
{
    // Attempt to roll back the transaction. 
    try
    {
        if (dbTransaction != null)
        {
            dbTransaction.Rollback();
        }
    }
    catch (Exception ex2)
    {
        // This catch block will handle any errors that may have occurred 
        // on the server that would cause the rollback to fail, such as 
        // a closed connection.
        Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
        Console.WriteLine("  Message: {0}", ex2.Message);
    }
    throw;
}

答案 1 :(得分:2)

YES!我遇到过同样的问题。可怕的答案是SQLServer有时会在遇到错误时回滚服务器端的事务,并且不会将错误传递回客户端。 YIKES!

查看Google Group microsoft.public.dotnet.framework.adonet for "SqlTransaction.ZombieCheck error" Colberd Zhou [MSFT]解释得非常好。

并查看aef123对this SO post

的评论

答案 2 :(得分:1)

我可以建议连接在事务提交之前关闭。然后回滚事务。 Check this article on MSDN Blog