TransactionScope性能问题

时间:2013-07-22 08:09:25

标签: c# performance wcf transactionscope

在服务器端代码(WCF)中使用TransactionScope类时出现性能问题。

我的代码从客户端获取请求,创建TransactionScope并执行简短操作(通常最多100毫秒)。

请参阅下面的模拟我的服务器端代码的附加代码。当有100个或更多并发用户时,它需要超过1秒!创建新的TransactionScope(请参阅GetTransaction()方法)。

当它达到200个并发用户时,抛出TransactionAborted。

你有什么想法吗?

class Program
     {
         private static ConcurrentQueue<double> m_Queue = new ConcurrentQueue<double>();

     static void Main(string[] args)
     {
         Console.WriteLine("Press any key to start ...");
         Console.ReadKey();

         for (int i = 0; i < 100; i++)
         {
             Thread t = new Thread(new ThreadStart(Method));
             t.IsBackground = true;
             t.Start();
         }

         Thread.Sleep(2000);
         Console.WriteLine("Max {0}, Min {1}, Avg {2}, Total {3}", m_Queue.Max(), m_Queue.Min(), m_Queue.Average(), m_Queue.Count);
         Console.ReadKey();
     }


     private static void Method() 
     {
         using (TransactionScope scope = GetTransaction())
         {
             Thread.Sleep(100);
             scope.Complete();
         }
     }

     public static TransactionScope GetTransaction()
     {
         var start = DateTime.Now;

         TransactionOptions options = new TransactionOptions();
         options.IsolationLevel = IsolationLevel.ReadCommitted;
         var t = new TransactionScope(TransactionScopeOption.Required, options);

         // Log creation time
         m_Queue.Enqueue((DateTime.Now.Subtract(start)).TotalMilliseconds);

         return t;
     }

 }

2 个答案:

答案 0 :(得分:0)

初步答复:

如果我使用简单的List而不是ConcurrentQueue(我没有安装.net 4.5)来测试它,那么你的代码就可以了。

由于你同时开始200个线程,你的行:

Console.WriteLine("Max {0}, Min {1}, Avg {2}, Total {3}", m_Queue.Max(), m_Queue.Min(), m_Queue.Average(), m_Queue.Count);

基本上开始遍历队列,这会阻塞队列,这会导致仍然起始线程在尝试将项目添加到队列时冻结,从而导致事务超时。 / p>

如果没有上面提到的控制台 - 写字线,你能试试吗? 另外,请使用普通列表进行尝试。

解决方法是在尝试执行max / min / avg / total函数之前等待线程完成。

有一点需要注意的是,我在测试中获得的总数不是100或200全部。它只是稍微低一点,这意味着仍有线程启动。

更新

如果有帮助的话。如果我在方法中移动enqueue调用,我遇到的任何问题都会得到解决。这会在你的情况下起作用吗?

public static TransactionScope GetTransaction() {
    var start = DateTime.Now;

    // Log creation time
    m_Queue.Enqueue((DateTime.Now.Subtract(start)).TotalMilliseconds);

    TransactionOptions options = new TransactionOptions();
    options.IsolationLevel = IsolationLevel.ReadCommitted;
    var t = new TransactionScope(TransactionScopeOption.Required, options);

    return t;
}

答案 1 :(得分:0)

删除“enqueue”行,查看问题是否仍然存在。

另一件事,我很好奇在交易范围内执行的“短期操作”。他们可能会将事务协调员从LTM升级到MSDTC,这可能解释了更多并发点击的缓慢。