SqlConnection挂起时打开

时间:2015-07-20 20:51:11

标签: c# sql-server sql-server-2008 sql-server-2012 sqlconnection

我有一个程序可以将多个请求并行发送到SQL Server实例。在我的所有并发请求中,其中一个总是在db.open()上阻塞几秒钟。

void MyMethod()
{
    var brands = new  List<string>{"Chevy", "Honda", "Ford", "GM"};
    var foundCars = new  ConcurrentBag<Car>();   

    Parallel.ForEach(brands, brand =>
    {
      logger.Trace(brand + " before enqueue");
      foundsCars.Enqueue(FindCar(brand));
      logger.Trace(brand + " after enqueue");
    });
}

public Car FindCars(string brand)
{
   using (var db = new SqlConnection(connectionString))
   {
     sqlLogger.Trace("Brand " + " brand " + " before db open");
     db.Open();
     sqlLogger.Trace("Brand " + " brand " + " after db open");
     using (var cmd = new SqlCommand(sqlCmd, db))
     {
        while (reader.Read())
        {              
            //SQL SELECT Stuff going on
        }
     }
   }
}

如果我查看我的跟踪,我会看到类似的东西,顺序取决于我想的数据库响应时间,在这种情况下,本田是数据正在缓慢处理,但它并不总是如此:

12:00:00.0000 Chevy before enqueue 
12:00:00.0000 Honda before enqueue 
12:00:00.0000 Ford before enqueue
12:00:00.0000 GM before enqueue
12:00:00.0200 Brand Chevy before db open
12:00:00.0300 Brand Honda before db open
12:00:00.0200 Brand Ford before db open
12:00:00.0200 Brand GM before db open
12:00:00.0300 Brand Chevy after db open
12:00:00.0300 Brand Ford after db open
12:00:00.0300 Brand GM after db open
12:00:00.0400 Chevy after enqueue
12:00:00.0400 Ford after enqueue
12:00:00.0400 GM after enqueue
12:00:07.0000 Brand Honda after db open <-- usually around 7 seconds late
12:00:07.0100 Honda after enqueue

我似乎无法在我的SQL Server 2008实例上本地复制此问题,但它始终在SQL Server 2012实例上发生。这个问题似乎是一个配置问题。它总是发生在我发送并发请求和SELECT请求时。如果我在SQL Server Management中执行阻塞查询,它将在100毫秒内返回。

这是我的连接字符串:

<add key="SqlConnectionString" value="Data Source=10.0.20.20;Initial Catalog=CarsDB;Integrated Security=SSPI;Connection Timeout=240;" />

修改

我插入&#34; Min Pool Size = 30&#34;在我的连接字符串中,似乎只有第一次,第二次或第三次方法被命中它在+15秒内运行,然后所有其他方法调用都是低于500毫秒。

我还在我们的测试环境中运行了SQL Server 2012,其中表中的元数据与发现问题的方式相同,我无法复制此问题。这似乎是某处的配置问题。

4 个答案:

答案 0 :(得分:1)

除非你有分区表,否则这是疯狂的

Parallel.ForEach(brands, brand =>
{
  logger.Trace(brand + " before enqueue");
  foundsCars.Enqueue(FindCar(brand));
  logger.Trace(brand + " after enqueue");
});

同一个表之后的多个连接并不快,更不用说多个连接的开销了。另一方面,您有一个物理读写头。你不是那么开放和关闭连接比简单阅读更长?真的,你只需将桌子排成一行并从中读取。读者非常快。

答案 1 :(得分:0)

尝试在ConnectionString中使用MARS。它看起来应该是Data Source=10.0.20.20;Initial Catalog=CarsDB;Integrated Security=SSPI;Connection Timeout=240;MultipleActiveResultSets=True;

答案 2 :(得分:0)

看起来连接池耗尽。 Parallel.ForEach容易发送垃圾邮件疯狂的线程数量。就我所知,对于某些IO工作负载而言,实际上是无限量的。将并行度限制为合理的值。

答案 3 :(得分:0)

将连接字符串中的集成安全性从SSPI切换到用户/密码解决了问题。看起来我们的环境之一存在Active Directory问题,而另一个环境没有问题。

相关问题