热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

SqlConnection的连接池机制解析

提供一篇关于sqlconnection连接池详细,有需要的朋友参考一下。

提供一篇关于sqlconnection连接池详细,有需要的朋友参考一下。

物理连接建立时,需要做和服务器握手,解析连接字符串,授权,约束的检查等等操作,而物理连接建立后,这些操作就不会去做了。这些操作是需要一定的时间的。所以很多人喜欢用一个静态对象存储 SqlConnection 来始终保持物理连接,但采用静态对象时,多线程访问会带来一些问题,实际上,我们完全不需要这么做,因为 SqlConnection 默认打开了连接池功能,当程序 执行 SqlConnection.Close 后,物理连接并不会被立即释放,所以这才出现当循环执行 Open操作时,执行时间几乎为0.

下面我们先看一下不打开连接池时,循环执行 SqlConnection.Open 的耗时

代码如下

public static void OpenWithoutPooling()
{
string cOnnectionString=
"Data Source=192.168.10.2; Initial Catalog=News; Integrated Security=True;Pooling=False;";

Stopwatch sw = new Stopwatch();

sw.Start();
using (SqlConnection cOnn=
new SqlConnection(connectionString))
{
conn.Open();
}

sw.Stop();
Console.WriteLine("Without Pooling, first connection elaed {0} ms", sw.ElapsedMilliseconds);

sw.Reset();

sw.Start();

for (int i = 0; i <100; i++)
{
using (SqlConnection cOnn= new SqlConnection(connectionString))
{
conn.Open();
}
}

sw.Stop();
Console.WriteLine("Without Pooling, average connection elapsed {0} ms", sw.ElapsedMilliseconds / 100);
}

SqlConnection 默认是打开连接池的,如果要强制关闭,我们需要在连接字符串中加入 Pooling=False

调用程序如下:

代码如下
Test.SqlConnectionTest.OpenWithoutPooling();
Console.WriteLine("Waiting for 10s");
System.Threading.Thread.Sleep(10 * 1000);
Test.SqlConnectionTest.OpenWithoutPooling();
Console.WriteLine("Waiting for 600s");
System.Threading.Thread.Sleep(600 * 1000);
Test.SqlConnectionTest.OpenWithoutPooling();

下面是测试结果

Without Pooling, first connection elapsed 13 ms
Without Pooling, average connection elapsed 5 ms
Wating for 10s
Without Pooling, first connection elapsed 6 ms
Without Pooling, average connection elapsed 4 ms
Wating for 600s
Without Pooling, first connection elapsed 7 ms
Without Pooling, average connection elapsed 4 ms

从这个测试结果看,关闭连接池后,平均每次连接大概要耗时4个毫秒左右,这个就是建立物理连接的平均耗时。

下面再看默认情况下的测试代码

代码如下

public static void OpenWithPooling()
{
string cOnnectionString=
"Data Source=192.168.10.2; Initial Catalog=News; Integrated Security=True;";

Stopwatch sw = new Stopwatch();

sw.Start();
using (SqlConnection cOnn=
new SqlConnection(connectionString))
{
conn.Open();
}

sw.Stop();
Console.WriteLine("With Pooling, first connection elapsed {0} ms", sw.ElapsedMilliseconds);

sw.Reset();

sw.Start();

for (int i = 0; i <100; i++)
{
using (SqlConnection cOnn= new SqlConnection(connectionString))
{
conn.Open();
}
}

sw.Stop();
Console.WriteLine("With Pooling, average connection elapsed {0} ms", sw.ElapsedMilliseconds / 100);
}


调用代码

Test.SqlConnectionTest.OpenWithPooling();
Console.WriteLine("Waiting for 10s");
System.Threading.Thread.Sleep(10 * 1000);
Test.SqlConnectionTest.OpenWithPooling();
Console.WriteLine("Waiting for 600s");
System.Threading.Thread.Sleep(600 * 1000);
Test.SqlConnectionTest.OpenWithPooling();
测试结果

With Pooling, first connection elapsed 119 ms
With Pooling, average connection elapsed 0 ms
Waiting for 10s
With Pooling, first connection elapsed 0 ms
With Pooling, average connection elapsed 0 ms
Waiting for 600s
With Pooling, first connection elapsed 6 ms
With Pooling, average connection elapsed 0 ms


这个测试结果看,第一次耗时是119ms,这是因为我在测试代码中,首先运行的是这个测试过程,119 ms 是程序第一次启动时的首次连接耗时,这个耗时可能不光包括连接的时间,还有 ado.net 自己初始化的用时,所以这个用时可以不管。10秒以后在执行这个测试过程,首次执行的时间变成了0ms,这说明连接池机制发生了作用,SqlConnection Close 后,物理连接并没有被关闭,所以10秒后再执行,连接几乎没有用时间。

但我们发现一个有趣的现象,10分钟后,首次连接时间变成了6ms,这个和前面不打开连接池的测试用时几乎一样,也就是说10分钟后,物理连接被关闭了,又重新打开了一个物理连接。这个现象是因为连接池有个超时时间,默认情况下应该在5-10分钟之间,如果在此期间没有任何的连接操作,物理连接就会被关闭。那么我们有没有办法始终保持物理连接呢?方法是有的。

连接池设置中有一个最小连接池大小,默认为0,我们把它设置为大于0的值就可以保持若干物理连接始终不释放了。看代码

代码如下

public static void OpenWithPooling(int minPoolSize)
{
string cOnnectionString=
string.Format("Data Source=192.168.10.2; Initial Catalog=News; Integrated Security=True;Min Pool Size={0}",
minPoolSize);

Stopwatch sw = new Stopwatch();

sw.Start();
using (SqlConnection cOnn=
new SqlConnection(connectionString))
{
conn.Open();
}

sw.Stop();
Console.WriteLine("With Pooling Min Pool Size={0}, first connection elapsed {1} ms",
minPoolSize, sw.ElapsedMilliseconds);

sw.Reset();

sw.Start();

for (int i = 0; i <100; i++)
{
using (SqlConnection cOnn= new SqlConnection(connectionString))
{
conn.Open();
}
}

sw.Stop();
Console.WriteLine("With Pooling Min Pool Size={0}, average connection elapsed {1} ms",
minPoolSize, sw.ElapsedMilliseconds / 100);
}


其实只要在连接字符串中加入一个 Min Pool Size=n 就可以了。

调用代码

代码如下

Test.SqlConnectionTest.OpenWithPooling(1);
Console.WriteLine("Waiting for 10s");
System.Threading.Thread.Sleep(10 * 1000);
Test.SqlConnectionTest.OpenWithPooling(1);
Console.WriteLine("Waiting for 600s");
System.Threading.Thread.Sleep(600 * 1000);
Test.SqlConnectionTest.OpenWithPooling(1);

With Pooling Min Pool Size=1, first connection elapsed 5 ms
With Pooling Min Pool Size=1, average connection elapsed 0 ms
Waiting for 10s
With Pooling Min Pool Size=1, first connection elapsed 0 ms
With Pooling Min Pool Size=1, average connection elapsed 0 ms
Waiting for 600s
With Pooling Min Pool Size=1, first connection elapsed 0 ms
With Pooling Min Pool Size=1, average connection elapsed 0 ms


我们可以看到当 Min Pool Size = 1 时,除了首次连接用时5ms以外,即便过了10分钟,用时还是0ms,物理连接没有被关闭。

推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 创建第一个 MUI 移动应用项目
    本文将详细介绍如何使用 HBuilder 创建并运行一个基于 MUI 框架的移动应用项目。我们将逐步引导您完成项目的搭建、代码编写以及真机调试,帮助您快速入门移动应用开发。 ... [详细]
  • 梦幻西游挖图奇遇:70级项链意外触发晶清诀,3000W轻松到手
    在梦幻西游中,挖图是一项备受欢迎的活动,无论是小宝图还是高级藏宝图,都吸引了大量玩家参与。通常情况下,小宝图的数量保证了稳定的收益,但特技装备的出现往往能带来意想不到的惊喜。本文讲述了一位玩家通过挖图获得70级晶清项链的故事,最终实现了3000W的游戏币逆袭。 ... [详细]
  • 本文探讨了 RESTful API 和传统接口之间的关键差异,解释了为什么 RESTful API 在设计和实现上具有独特的优势。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 如何配置Unturned服务器及其消息设置
    本文详细介绍了Unturned服务器的配置方法和消息设置技巧,帮助用户了解并优化服务器管理。同时,提供了关于云服务资源操作记录、远程登录设置以及文件传输的相关补充信息。 ... [详细]
  • 网络攻防实战:从HTTP到HTTPS的演变
    本文通过一系列日记记录了从发现漏洞到逐步加强安全措施的过程,探讨了如何应对网络攻击并最终实现全面的安全防护。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 邮件(带附件,模拟文件上传,跨服务器)发送核心代码1.测试邮件发送附件接口***测试邮件发送附件*@parammultipartFile*@return*@RequestMappi ... [详细]
  • 360SRC安全应急响应:从漏洞提交到修复的全过程
    本文详细介绍了360SRC平台处理一起关键安全事件的过程,涵盖从漏洞提交、验证、排查到最终修复的各个环节。通过这一案例,展示了360在安全应急响应方面的专业能力和严谨态度。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文探讨了在不使用服务器控件的情况下,如何通过多种方法获取并修改页面中的HTML元素值。除了常见的AJAX方式,还介绍了其他可行的技术方案。 ... [详细]
author-avatar
518094haha
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有