2011-06-19 65 views
4

我在我的代码中使用TransactionScrope在SQL Server 2008 R2上执行50 SQL命令。 这是我的代码示例:来自TransactionScope的不清楚的异常

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分钟,那么在长命令之后执行下一个命令将导致发生异常。

有没有人知道这个原因?

感谢您的帮助!

+0

6个小时的交易报价诚实疯狂。非常糟糕的巫术。交易应该*非常简短。我不认为这有帮助。我会重新设计这个... –

回答

3

我想试试这里的事情很简单,就是移动完成交易连接,即

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

    if(isComplete) 
     tran.Complete(); 
} 

还要注意的是倍,很容易简单地让异常处理旁路完成()对我们来说,即

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

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

我试过这个,但仍然不工作... 10分钟后,下一个sqlCommand返回相同的异常。任何其他想法? – user436862

+0

@ user436862我的*主要*的想法是,这项工作太大了,不能在交易中... 10分钟? 6个小时?大多数交易最后(最多)*秒* –

+1

我得到int到bigint的转换表的交易。我创建了空表并复制了4个由int键绑定的表中的所有记录(在bigint键中的新表中),因此我需要将旧表中的所有数据插入到新的一个事务中。因为我有数百万条记录,这个交易需要15分钟以上的时间...... – user436862

1

听起来像事务只是超时看到它在一段时间后失败。