来自TransactionScope的不明确异常

时间:2011-06-19 07:14:51

标签: c# sql stored-procedures ado.net transactionscope

我在我的代码中使用TransactionScrope在SQL Server 2008 R2上执行50 SQL命令。 这是我的代码的一个例子:

   private void DoSomething()
    {
        bool IsComplete = false;
        SqlCommand sqlComm = null;
        //6 hours!!!
        TimeSpan ts1 = new TimeSpan(6, 0, 0);
        try
        {
            using (TransactionScope t = new TransactionScope(TransactionScopeOption.RequiresNew, ts1))
            {
                using (SqlConnection sqlConn = new SqlConnection(GetConnectionString()))
                {
                    //open sql connection
                    sqlConn.Open();
                    try
                    {
                        //create new sqlCommand
                        sqlComm = new SqlCommand();
                        for (int i = 1; i <= 2; i++)
                        {
                            IsComplete = true;
                            //This command takes 15 minutes
                            sqlComm.CommandText = "exec TestSp";
                            sqlComm.Connection = sqlConn;
                            sqlComm.CommandType = CommandType.Text;
                            sqlComm.CommandTimeout = 18000;
                            //Executing my command
                            int j = sqlComm.ExecuteNonQuery();
                            sw.WriteLine("Finsh Executing SQL Command:" + DateTime.Now.ToLongTimeString());
                            sw.Flush();
                        }
                        //End
                        IsComplete = true;
                    }
                    catch (Exception ex)
                    {
                        IsComplete = false;
                        string Message = ex.Message;
                    }
                    finally
                    {
                        if (sqlComm != null)
                            sqlComm.Dispose();
                        if (IsComplete)
                            t.Complete();
                    }
                }
            }
        }
        catch (Exception ex)
        {
            string messagee = ex.Message;
            //do something
        }
        finally
        {
            MessageBox.Show("Finsh");
        }
    }

当程序超过10分钟时,我得到了这个例外:

  

与当前连接关联的事务已完成但尚未处理。必须先处理事务,然后才能使用连接执行SQL语句。

通过更改TimeSpam和更改SqlCommand.Timout,我厌倦了很多选项,但由于某种原因,我得到了这个例外。在第一次执行需要花费大量时间后发生异常。例如,如果我有100个存储过程和文本命令,并且所有命令花费的时间少于5分钟,并且只有一个命令需要超过10分钟,则在long命令之后执行下一个命令将导致异常发生。

有没有人知道原因?

感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

我认为在这里尝试的只是将交易完成移到连接之外,即

using(var tran = ...)
{
    bool isComplete;
    using(var conn = ...)
    {
         //...
    }

    if(isComplete)
        tran.Complete();
}

另请注意大多数次,更容易让异常处理绕过Complete(),即

using(var tran = ...)
{
    using(var conn = ...)
    {
        //...
    }

    // if we get an exception, we won't get here
    tran.Complete();
}

答案 1 :(得分:3)

当事务运行的时间比maxTimeout的{​​{1}}更长时,可能会发生此错误。 System.Transactions的默认值为10分钟。

您可以在以下答案中详细了解相关内容:https://stackoverflow.com/a/10017056/205023或在此博文中:http://thecodesaysitall.blogspot.se/2012/04/long-running-systemtransactions.html

答案 2 :(得分:1)

听起来这个交易刚刚超时,看到它在一段时间后失败了。