SQLTransaction已完成错误

LCJ*_*LCJ 12 .net c# ado.net transactionscope

我在申请中遇到了一次错误.

这个SQLTransaction已经完成; 它不再可用

堆栈跟踪附在下面 - 它说Zombie CheckRollback.

代码中的错误是什么?

注意:此错误只出现一次.

UPDATE

MSDN - SqlTransaction.Rollback方法

如果连接终止或者事务已在服务器上回滚,则Rollback会生成InvalidOperationException.

僵尸检查交易 - 错误

我在各种应用程序中看到此错误的最常见原因之一是,在我们的应用程序中共享 SqlConnection.

public int SaveUserLogOnInfo(int empID)
{
        int? sessionID = null;
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            SqlTransaction transaction = null;
            try
            {
                transaction = connection.BeginTransaction();
                sessionID = GetSessionIDForAssociate(connection, empID, transaction);

                    //Other Code

                //Commit
                transaction.Commit();
            }
            catch
            {
                //Rollback
                if (transaction != null)
                {
                    transaction.Rollback();
                    transaction.Dispose();
                    transaction = null;
                }

                //Throw exception
                throw;
            }
            finally
            {
                if (transaction != null)
                {
                    transaction.Dispose();
                }
            }
        }

        return Convert.ToInt32(sessionID,CultureInfo.InvariantCulture);

   }
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪

在此输入图像描述


参考:

  1. 什么是僵尸交易?
  2. 僵尸检查交易 - 错误
  3. SqlTransaction已经完成
  4. http://forums.asp.net/t/1579684.aspx/1
  5. "这个SqlTransaction已经完成;它已不再可用."...配置错误?
  6. dotnet.sys-con.com - 暴露的SqlClient连接池
  7. 线程中止离开僵尸事务并破坏SqlConnection

Mar*_*ell 7

注意:此错误只出现一次.

那说起来很难; 可能只是// Other Code等等只是花了很长时间,整个事情都被杀死了.也许你的连接已经死亡,或者管理员故意杀死它,因为你阻止了.

代码中的错误是什么?

过度复杂化; 它可以更简单:

using (var connection = new SqlConnection(connectionString))
{
    connection.Open();
    using(var transaction = connection.BeginTransaction())
    {
        try
        {
            sessionID = GetSessionIDForAssociate(connection, empID, transaction);
            //Other Code
            transaction.Commit();
         }
         catch
         {
            transaction.Rollback();
            throw;
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

错误的代码要少得多.

  • @Lijo,因为你没有可重复的例子,所以不可能谈论"解决问题".我的建议很简单:你很容易引入微妙的错误 - 这是有风险的,不必要的,*和更多的工作*.*永远不会被写入的不必要的代码*没有任何错误. (4认同)
  • 在你的情况下你可以保存更多的行,如果你删除try catch ..使用"using"语句,如果发生异常,事务会自动回滚..请参阅http://msdn.microsoft.com/en-us /library/system.data.sqlclient.sqltransaction.aspx (3认同)
  • 我喜欢这一点 - `永远不会写的代码没有任何错误`:-) (2认同)

Nik*_*vić 7

你应该把一些工作留给编译器,把它包装在try/ catch/ finally中.

此外,Rollback如果Commit阶段出现问题,或者与服务器的连接中断,您应该会偶尔抛出异常.因此,您应该将其包装在try/中catch.

try
{
    transaction.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);
}
Run Code Online (Sandbox Code Playgroud)

这完全是从用于Rollback方法的MSDN文档页面复制的.

我看到你担心你有一个僵尸交易.如果你粘贴了,听起来不像你有问题.您的交易已经完成,您不应该再与它有任何关系了.如果你持有它们,删除它的引用,并忘记它.


MSDN - SqlTransaction.Rollback方法

如果连接终止或者事务已在服务器上回滚,则Rollback会生成InvalidOperationException.

重新抛出一个新的异常,告诉用户数据可能尚未保存,并要求她刷新和查看