首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TransactionScope性能问题

TransactionScope性能问题
EN

Stack Overflow用户
提问于 2013-07-22 16:09:25
回答 2查看 1.5K关注 0票数 3

在我的服务器端代码中使用TransactionScope类时,我遇到了性能问题。

我的代码从客户端获取请求,创建TransactionScope并执行短操作(通常长达100ms)。

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

当并发用户数达到200时,就会抛出TransactionAborted。

你有什么想法吗?

代码语言:javascript
复制
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;
     }

 }
EN

回答 2

Stack Overflow用户

发布于 2013-07-22 16:32:29

初始答案:

如果我用一个简单的列表而不是ConcurrentQueue (我没有安装.net 4.5 )来测试它,你的代码在我这一端运行得很好。

由于您同时启动了200个线程,因此您的代码行:

代码语言:javascript
复制
Console.WriteLine("Max {0}, Min {1}, Avg {2}, Total {3}", m_Queue.Max(), m_Queue.Min(), m_Queue.Average(), m_Queue.Count);

基本上开始遍历队列,这会阻塞队列,这会导致仍在启动的线程在尝试将项添加到队列时冻结,进而导致事务超时。

你可以在没有上面提到的控制台-writeline的情况下尝试一下吗?另外,用一个普通的列表来尝试它。

一种解决方案是等待线程完成,然后再尝试执行max/min/avg/total函数。

需要注意的一件事是,我在测试中得到的总数不是全部的100或200。它就在下面一点,这意味着仍然有线程在启动。

更新:

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

代码语言:javascript
复制
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;
}
票数 0
EN

Stack Overflow用户

发布于 2013-07-22 18:54:24

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

另外,我对事务作用域中执行的“短操作”很好奇。他们可能会将事务协调器从LTM升级到MSDTC,这可能解释了并发命中率更高的缓慢原因。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17782676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档