‘關於數據庫連接池大家都聽說過或者用過,但真正的了解有多少呢?
- 數據連接池如何啟用?有哪些主要的參數?
- 為什么要使用連接池?
- 如何關閉連接池?
- 如何在不開啟新的連接池情況下切換當前數據庫?
- 連接池的生命周期?
- 當數據庫服務器強制關閉連接時會怎么樣?
==============================================================================================================================
首先說明一下測試環境:
數據庫版本:SQL SERVER 12.0.2269.0 [Microsoft SQL Server 2014 Enterprise (64-bit)]
C#版本: Microsoft Visual C# 2015 14.0.25431
客戶端版本:System.Data 4.0.0
首先創建一個數據庫訪問類,便於測試:
public class DbAccepter
{
/// <summary>
/// 數據庫連接
/// </summary>
private SqlConnection _conn = new SqlConnection();
/// <summary>
/// 數據庫連接字符串
/// </summary>
private String _connectionString = "";
/// <summary>
/// 數據庫連接字符串
/// </summary>
public string ConnectionString
{
get
{
return _connectionString;
}
set
{
_connectionString = value;
_conn.ConnectionString = _connectionString;
}
}
public DataTable GetData(string sql)
{
string sss = _conn.State.ToString();
using (SqlCommand cmd = new SqlCommand(sql, _conn))
{
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
_conn.Open();
adapter.Fill(ds);
_conn.Close();
return ds.Tables[0];
}
}
}
}
1.如何開啟連接池?
只需要連接字符串中加入對應的選項即可:
private static String _connectionString = "pooling=true;connection lifetime=5;min pool size = 2;max pool size=4;
Data Source = 127.0.0.1; Initial Catalog = tempdb; User ID = test; Password=Sm5lAXQiZ10L";
注意里面和連接池有關的參數:
pooling=true; --表示開啟連接池(默認為開啟)
min pool size = 2 --最小連接池大小:即什么也沒執行初次連接的時候先和數據庫服務建立n個連接
max pool size=4 --最大連接池大小:允許建立的最大連接數,是在需要的時候建立。
舉例說明:min pool size = 2;max pool size=4 ;
點擊按鈕時調用以下代碼執行數據庫腳本。
try
{
info.Clear();
for (int i = 0; i < num.Value; i++)
{
Thread th = new Thread(GetCurrentDbName);
th.Start();
}
}
catch (Exception ex)
{
listboxAdd(ex.Message);
}
這里的GetCurrentDbName方法是創建數據庫連接然后執行一段SQL腳本,獲取當前數據庫的名稱然后延時3S,所以每次執行SQL的時間都約為3秒
select db_name(); waitfor delay '00:00:03'; --延遲3秒
這里我們先將並發數設為1,在初次建立連接時會創建2個連接。

可以在數據庫中進行查看:
select * from sysprocesses where hostname='xxx' and loginame='test'

2. 那連接池是和有什么有關呢?
在同一個進程中,只和連接字符串有關,只要連接字符串一樣就會使用同一個連接池。
這里我們將連接字符串改為下圖(只修改了最小數據池):

執行指令后,再觀察一下數據庫的連接信息:

我們發現會多出一個連接信息,可以會懷疑是不是使用的同個連接池。你可以將並發數改為4.

可以看到,這時的連接數變為6,之前的連接字符串占用了兩個,修改后的占用了4個。因為連接池的大小限制為4,所以說明確實是使用了兩個連接池。
當我們的並發請數大於最大連接池數會怎么樣?這里我們修改一下之前的程序代碼,記錄線程調用方法執行的起止時間

9個線程的執行截止時間,可以看出前四的截止時間基本相同,中間的四個大約比前4個晚3S。最后一個比中間四個晚3S。
說明開始有4個線程的數據庫請求獲取到連接池資源,其它線程等待。
這4個線程執行完成后,另4個線程獲的連接池資源,最后一個線程等待真到再次釋放連接池。
那我們再看一下數據庫的連接數仍然為4。說明有多個並行請求時,超過連接池的部分將等待。等待多久會超時呢???
結論是如果想使用連接池,必須使用相同的連接字符串,必須一字不差(我並沒有全部測試)。
3.如何使用相同的連接池訪問不同的數據庫?
在實際開發中我們會訪問同一個服務器中的多個數據庫,但又不想創建過多的連接。如果訪問不同的庫使用不同的連接字符串,那就會產生多個連接池。
如這樣:
pooling=true;connection lifetime=10;min pool size = 2;max pool size=4; Data Source = 127.0.0.1; Initial Catalog = tempdb; User ID = test; Password=Sm5lAXQiZ10L pooling=true;connection lifetime=10;min pool size = 2;max pool size=4; Data Source = 127.0.0.1; Initial Catalog = master; User ID = test; Password=Sm5lAXQiZ10L
這時有兩個辦法:
1.在SQL語句中指定數據庫名稱(不太靠譜)
2.不要重新創建連接,而是使用的相同的連接字符串創建連接后再切換數據庫。實現代碼如下:
using (SqlCommand cmd = new SqlCommand(sql, _conn))
{
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
_conn.Open(); //這時指向的是tempdb
_conn.ChangeDatabase("master"); //切換數據庫
adapter.Fill(ds);
_conn.Close();
return ds.Tables[0];
}
}

