標籤:
c#與oracle資料庫連接池
在做一個項目,中間要使用webservice和oracle資料庫.我在服務端做了使用者身份認證,也就是使用session傳遞使用者的登陸資訊.在測試時,當使用者少的時候,沒有問題,但是當大量使用者同時訪問時,就報錯,起初以為是自己的oracle串連部分有問題,幾經確認,終於發現了是串連池的問題.
以下是從別人的部落格中摘抄的,不敢造次,收錄如下:
"串連根據連接字串以及使用者標識來建立池串連。因此,如果使用網站上的基本驗證或 Windows 身分識別驗證以及整合的安全登入,每個使用者將獲得一個池。儘管這樣可以提高單個使用者的後續資料庫請求的效能,但是該使用者無法利用其他使用者建立的串連。這樣還使每個使用者至少產生一個與資料庫伺服器的串連。這對特定 Web 應用程式結構會產生副作用,因為開發人員需要衡量安全性和審計要求。
"
這也許就是問題的所在吧.
Oracle串連池
原由:許多使用者可能在查詢相同的資料庫以擷取相同的資料。在這些情況下,可以通過使應用程式共用到資料來源的串連來提高應用程式的效能。否則,讓每個使用者開啟和關閉單獨的串連的開銷會對應用程式效能產生不利影響。這樣就有了串連池。
實現:
C#在連接字串中設定串連池。
如果使用的是 OleDbConnection、OdbcConnection 或 OracleConnection 類,則串連池將由提供者自動處理,所以您不必自己進行管理。
如果使用的是 SqlConnection 類,則串連池被隱式管理,但也提供選項允許您自己管理池。
串連使用Open()方法開啟串連,這時候串連池就會初始化並建立設定的最小串連數。在使用完串連時一定要關閉串連,以便串連可以返回池。要關閉串連使用Close()
當串連數滿了並且申請串連的時間超過設定串連等待的時間時,使用“非同步進程”,對資料庫進行非同步作業,確保串連能夠及時調用Close方法關閉串連,這樣能大大減少正在使用的串連數。
當資料庫操作和訪問頻繁的時候,減少建立串連和開啟串連所耗的時間,提升資料庫伺服器的效能。 這裡將詳細分析C#資料庫串連池。
使用C#資料庫串連池
串連到資料庫伺服器通常由幾個需要軟長時間的步驟組成。必須建立物理通道(例如通訊端或具名管道),必須與伺服器進行初次串連,必須分析連接字串資訊,必須由伺服器對串連進行身分識別驗證,等等。
實際上,大部份的應用程式都是使用一個或幾個不同的串連配置。當應用程式的資料量和訪問量大的時候,這意味著在運行應用程式的過程中,許多相同的串連將反 複地被開啟和關閉,從而會引起資料庫伺服器效率低下甚至引發程式崩潰。為了確保應用程式的穩定和降低效能成本,我們可以在ADO.NET中使用稱為串連池的最佳化方法來管理維護串連。
C#資料庫串連池可以減少建立串連的次數。定義最小串連數(固定串連數),當使用者在串連上調用Open,串連池就會檢查池中是否有可用的串連。如果發現有串連可用,會將該串連返回給調用者,而不是建立新串連。應用程式在該串連上調用Close時,串連池會判斷該串連是否在最小串連數之內,如果“是”會將串連回收到活動串連池中而不是真正關閉串連,否則將燒毀串連。串連返回到池中之後,即可在下一個Open調用中重複使用。
建立C#資料庫串連池
以下樣本使用C#串連SQL資料庫:
class DbConn
{
//using System.Data;
//using System.Data.SqlClient;
private const int MaxPool = 10; //最大串連數
private const int MinPool = 5; //最小串連數
private const bool Asyn_Process = true; //設定非同步訪問資料庫
private const bool Mars = true; //在單個串連上得到和管理多個、僅向前引用和唯讀結果集(ADO.NET2.0)
private const int Conn_Timeout = 15; //設定串連等待時間
private const int Conn_Lifetime = 15; //設定串連的生命週期
private string ConnString = ""; //連接字串
private SqlConnection SqlDrConn = null; //連線物件
public DbConn()//建構函式
{
ConnString = GetConnString();
SqlDrConn = new SqlConnection(ConnString);
}
private string GetConnString()
{
return "server=localhost;"
+ "integrated security=sspi;"
+ "database=pubs;"
+ "Max Pool Size=" + MaxPool + ";"
+ "Min Pool Size=" + MinPool + ";"
+ "Connect Timeout=" + Conn_Timeout + ";"
+ "Connection Lifetime=" + Conn_Lifetime + ";"
+"Asynchronous Processing=" + Asyn_Process + ";";
//+ "MultipleActiveResultSets=" + Mars + ";";
}
public DataTable GetDataReader(string StrSql)//資料查詢
{
//當串連處於開啟狀態時關閉,然後再開啟,避免有時候資料不能及時更新
if (SqlDrConn.State == ConnectionState.Open)
{
SqlDrConn.Close();
}
try
{
SqlDrConn.Open();
SqlCommand SqlCmd = new SqlCommand(StrSql, SqlDrConn);
SqlDataReader SqlDr = SqlCmd.ExecuteReader();
if (SqlDr.HasRows)
{
DataTable dt = new DataTable();
//讀取SqlDataReader裡的內容
dt.Load(SqlDr);
//關閉對象和串連
SqlDr.Close();
SqlDrConn.Close();
return dt;
}
return null;
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
return null;
}
finally
{
SqlDrConn.Close();
}
}
}
通過調用SqlDrConn.Open()方法開啟串連,這時候串連池就會初始化並建立設定的最小串連數。想更清楚瞭解到串連池的 狀況可以通過SQL的查詢分析器執行預存程序sp_Who,它會列出當前的資料庫進程,查看loginname、dbname可以區分使用者的串連資訊,但 要注意的是登入查詢分析器本身會使用兩個串連,所以最好用另一個使用者名稱登入查詢分析器。使用此方法還有一個麻煩地方就是要經常按“執行查詢”以更新進程信 息。還有另一種方法個人認為較好的,通過控制台→管理工具→效能,右擊添加計算機,效能物件選擇 SQlServer:GeneralStatistics(常規統計)然後計算機選擇UserConnections(使用者串連)最後按“添加”就可以實 時查看當前串連數。
到了這裡,串連池已經實現了,但問題往往會出現在運行過程中。如串連池的串連數滿 了該怎樣處理?在這裡我們應該合理設定連接字串中的ConnectTimeout屬性和ConnectionLifetime屬性(上面有解釋)延長等 待時間,儘可能地在每次使用完串連之後調用Close方法關閉串連。但從中也有沒法避免的,當串連數滿了並且申請串連的時間超過設定串連等待的時間時,程 序將會引發InvalidOperationExceptio異常,我們可以通過捕獲此異常向使用者介面提示“系統正忙,請稍後再串連……”之類的資訊來緩 解這種情況。此外,也有另一種方法來解決這種情況,就是利用ADO.NET2.0新特性“非同步進程”,對資料庫進行非同步作業,確保串連能夠及時調用 Close方法關閉串連,這樣能大大減少正在使用的串連數。
使用方法:在連接字串中加上AsynchronousProcessing=true表示使用非同步處理操作。
當應用程式不再需要用到串連池的時候可以使用ClearPool或ClearAllPools方法清空串連池也可作重設串連池使用,方法如下:
SqlConnection.ClearPool(SqlConnectionconnection)清空關聯的串連池
SqlConnection.ClearAllPools()清空所有串連池
調用上述方法,如果串連正在使用,串連池會做相應標記,等串連關閉時自動燒毀。
小結C#資料庫串連池
優點:當資料庫操作和訪問頻繁的時候,減少建立串連和開啟串連所耗的時間,提升資料庫伺服器的效能。
缺點:資料庫串連池中可能存在著多個沒有被使用的串連一直串連著資料庫,這意味著資源的浪費。
c#與oracle資料庫連接池