关于SQLSERVER数据库连接池
‘关于数据库连接池⼤家都听说过或者⽤过,但真正的了解有多少呢?
数据连接池如何启⽤?有哪些主要的参数?
为什么要使⽤连接池?
如何关闭连接池?
如何在不开启新的连接池情况下切换当前数据库?
连接池的⽣命周期?
当数据库服务器强制关闭连接时会怎么样?
==============================================================================================================================⾸先说明⼀下测试环境:
数据库版本:SQL SERVER 12.0.2269.0 [Microsoft SQL Server 2014 Enterpri (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;
}
t
{
_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.Clo();
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; Ur 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秒lect db_name();
waitfor delay '00:00:03'; --延迟3秒
这⾥我们先将并发数设为1,在初次建⽴连接时会创建2个连接。
可以在数据库中进⾏查看:
lect * from sysprocess 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; Ur 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; Ur 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.ChangeDataba("master"); //切换数据库
adapter.Fill(ds);
_conn.Clo();
return ds.Tables[0];
}
}