2010-07-27 102 views
2

在下面的代码中,Provider对象只有一个DbConnection实例。每个阅读器将引用相同的连接实例。根据Microsoft文档,第二个阅读器将从连接池获得第二个连接。这工作正常。ADO.net连接池

using (var reader1 as IDataReader = Provider.GetReader(sqlStatement1)) 
{ 
    while(reader1.Read()) 
    { 
     using (var reader2 as IDataReader = Provider.GetReader(sqlStatement2)) 
     { 
      while(reader2.Read()) 
      { 
      //Do stuff with both statements 
      } 
     } 
    } 
} 

我想离开连接,只要我使用Provider对象。但是,我不想浪费连接池中的连接。将调用Provider.DbConnection.Close()尝试将两个连接都返回到池?如果是这样,我怎么能返回到连接池的第二个连接?

回答

1

经过测试不同的连接提供商后,我找到了我的答案。

OleDb提供程序维护与SqlClient提供程序不同的连接池。通常SqlClient提供程序应在每次要连接到数据库时都创建一个新的SqlConnection对象。连接应该关闭或处理。这将释放底层连接到池中。

然而,OleDb提供程序的处理方式不同。不要每次都实例化一个新的连接,而是应该使用同一个连接对象并将其放置在应用程序的末尾。如果使用与SqlClient连接相同的方式,并且引发错误“未指定的错误”。每个OleDbCommand可以被赋予相同的OleDbConnection实例。如果它已被使用,则底层提供者将为其分配新的连接。使用SqlClient提供程序执行此操作会产生一个异常。

我原来的连接字符串是这样的: Data Source = .... mdb; Provider = Microsoft.Jet.OLEDB.4.0;事实证明,这是128连接后失败......带有非常友好的“未指定的错误”。在研究连接池(不是错误)后,需要添加此参数才能打开连接池。 OLE DB Services = -1;

打开后,连接按预期工作,没有达到限制。

0

我会诚实地尝试重构,这样你就不需要一次有两个开放的阅读器。通过持续使用资源的时间超过实际需要的时间,您会打开自己以增加数据库中死锁的可能性。

这个问题有时被称为SELECT 1 + N:对于第一个select中返回的每一行,您正在执行额外的select。你将需要重构来解决这个问题,但这一切都取决于你想读的数据类型。

+0

其实,这只是一个专注于连接的人为的例子。真实世界的场景是我有一个长时间运行的后台进程访问数据库。用户正在进行搜索。我相信这个例子捕捉了处理手动释放连接的重点。 – Sam 2010-07-27 16:51:22