我在我的代码中使用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命令之后执行下一个命令将导致异常发生。
有没有人知道原因?
感谢您的帮助!
答案 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)
听起来这个交易刚刚超时,看到它在一段时间后失败了。