了解transactioncope超时

时间:2012-04-07 14:56:04

标签: c# asp.net sql-server-2008 transactionscope

我目前对transactioncope超时的理解。

如果某个事务的运行时间超过了设置的超时时间,那么它会抛出异常 调用transaction.complete()。因此,如果交易中的处理已经进行 对于X分钟,我们仍然需要等待X分钟,然后调用transaction.complete。

在我们的例子中,我们在webservice中使用transactionscope-- web请求的最终用户 在事务中止之前必须等待X分钟并且异常冒泡。

但是,HttpWebRequest的默认超时是100秒(根据msdn)。由于客户时间 在100秒内我们在一分钟的事务处理器中超时。这确保了数据库一致性

我对超时的理解是否正确?

问题:我们希望最大限度地缩短最终用户了解交易结果所需的时间。为了最大限度地减少延迟,我们决定使用嵌套的事务管理器拆分代码 - 每个事务处理器的超时时间为15秒。如果子交易花费的时间超过15秒,我们将整个交易中止。

这里似乎忽略了子事务的超时。我之后才得到例外 调用父事务的超时。在以下代码中,ChildTransaction()始终返回true。 什么是最小化延迟的建议方法? 代码显示默认超时为1分钟,因此代码更清晰

    internal bool RootTransaction()
    {           
        using (TransactionScope transaction = new TransactionScope())
        {
            try
            {
                bool result = ChildTransaction();

                //The result is always true. 
                if (!result)
                    return result;                                     

                for (int counter = 0;counter <= 10;counter++)
                {                       
                    //Either sleep OR do some processing 
                    System.Threading.Thread.Sleep(5000);
                    //
                    //Dosomeprocess()
                }                    
                transaction.Complete();                    
                return true;
            }
            catch (Exception e)
            {                    
                return false;
            }
        }                           
    }

    internal bool ChildTransaction()
    {            
        using (TransactionScope transaction = new TransactionScope())
        {
            try
            {
    //Sleep for 70 seconds
                System.Threading.Thread.Sleep(70000);
                transaction.Complete();                    
            }                
            catch (Exception e)
            {
                return false;
            }                
        }
        return true;
    }

1 个答案:

答案 0 :(得分:1)

尝试以这种方式看待它:

只有在调用trans.Complete()或退出事务范围时才会确定事务的长度。请使用以下代码:

using (var trans= new TransactionScope())
{
Threading.Sleep(99999);
trans.Complete()
}

在睡眠例程中没有办法抛出超时异常,如果有的话就没有意义。因此,使用事务超时(至少这种方式)只能保证如果事务所需的时间超过超时,则不会提交。

如果您只是执行一个查询(我不知道您使用什么交易),那么您可以设置查询/命令超时(或任何您称之为)。 IIRC,您的查询将在超时到期后立即返回。

另一种方法是设置您的Web服务请求超时,并假设Web服务由于您的事务内部的任何内容而花费太长时间来响应。

编辑: 你可以尝试:

  • 在另一个线程上生成您的事务,然后在主线程(webservice调用使用的线程)上等待它完成(使用Thread.Join(timeout))。因此,如果它在您指定的超时之前没有终止,那么您可以停止等待并返回超时错误(不要忘记发信号通知另一个线程中止事务)。
  • 假设您只在这些事务中执行SQL查询,您可以使用“BEGIN TRANSACTION”关键字在sql脚本中指定事务(确实是hacky)。然后你可以只指定命令超时并在一行代码中执行所有这些操作。但是这需要你将你在事务中所做的一切都移动到一个sql脚本中,这对你来说可能是也可能是不可能的......而且它并不干净。