4

我目前对 transactionscope 超时的理解。

如果事务运行时间超过设置的超时时间,则在调用 transaction.complete() 时会引发异常。因此,如果事务中的处理已经进行了 X 分钟,我们仍然需要等待 X 分钟,之后才会调用 transaction.complete。

在我们的例子中,我们在 web 服务中使用 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;
    }
4

1 回答 1

2

试着这样看:

事务的长度仅在您调用 trans.Complete() 或退出事务范围时确定。采取以下代码:

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

在 sleep 例程中没有办法抛出超时异常,如果这样做是没有意义的。所以使用事务超时(至少这样)只能保证如果事务花费的时间比你的超时时间长,它就不会被提交。

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

另一种方法是设置您的 Web 服务请求超时,并假设 Web 服务响应时间过长,因为您的事务中有任何内容。

编辑:您可以尝试:

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