TransactionScope的异常不明确

4

我在代码中使用TransactionScope来在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分钟,那么在长命令之后执行下一个命令将导致异常发生。
请问有人知道原因吗?
感谢您的帮助!

一个6小时的事务实在是太疯狂了。非常糟糕的巫术。事务应该非常简短。我不认为这会有所帮助。我会重新设计这个... - Marc Gravell
3个回答

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();
}

我尝试了这个,但仍然不起作用... 10分钟后,下一个sqlCommand返回相同的异常。还有其他想法吗? - user436862
@user436862,我的主要想法是这项工作太大了,无法在一个事务中完成... 10分钟?6小时?大多数事务最多只持续几秒钟。 - Marc Gravell
1
我获取了一份 int 到 bigint 的转换表事务。我创建了一个空表,并将所有绑定在 int 键上的 4 张表中的记录复制到新表中(通过 bigint 键),因此我需要逐个事务地将旧表中的所有数据插入到新表中。由于我有数百万条记录,这个事务需要超过 15 分钟的时间... - user436862

3

1
听起来像是交易只是在超过一定时间后失败了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接