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

Mr.*_*ble 14 sql-server transactions

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

using (var db = new MyDbDataContext(_dbConnectionString))
{
    Action action = new Action();
    db.Actions.InsertOnSubmit(dbAction);
    db.SubmitChanges();
}
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

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

有谁知道还有什么可能导致这个?

Ale*_*ici 11

该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;
}
// ...
Run Code Online (Sandbox Code Playgroud)

当连接超时时,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;
}
Run Code Online (Sandbox Code Playgroud)


Sto*_*leg 2

我可以建议在事务提交之前关闭连接吗?然后事务被回滚。在 MSDN 博客上查看这篇文章。