2010-07-27 191 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