本篇文章起源于在GCR MVP Open Day的时候和C# MVP张响讨论连接池的概念而来的。因此单独写一篇文章剖析一下连接池。

为什么需要连接池

剖析一个技术第一个要问的是,这项技术为什么存在。

对于每一个到SQL Server的连接,都需要经历TCP/IP协议的三次握手,身份认证,在SQL Server里建立连接,分配资源等。而当客户端关闭连接时,客户端就会和SQL Server终止物理连接。但是,我们做过数据库开发的人都知道,每次操作完后关闭连接是再正常不过的事了,一个应用程序即使在负载不大的情况下也需要不停的连接SQL Server和关闭连接,同一个应用程序同时也可能存在多个连接。

因此,如果不断的这样建立和关闭连接,会是非常浪费资源的做法。因此Ado.net中存在连接池这种机制。在对SQL Server来说的客户端的应用程序进程中维护连接池。统一管理Ado.net和SQL Server的连接,既连接池保持和SQL Server的连接,当Connection.Open()时,仅仅从连接池中分配一个已经和SQL Server建立的连接,当Connection.Close()时,也并不是和SQL Server物理断开连接,仅仅是将连接进行回收。

因此,连接池总是能维护一定数量的和SQL Server的连接,以便应用程序反复使用这些连接以减少性能损耗。

重置连接的sys.sp_reset_connection

连接是有上下文的,比如说当前连接有未提交的事务,存在可用的游标,存在对应的临时表。因此为了便于连接重复使用,使得下一个连接不会收到上一个连接的影响,SQL Server通过sys.sp_reset_connection来清除当前连接的上下文,以便另一个连接继续使用。

当在Ado.net中调用了Connection.Close()时,会触发sys.sp_reset_connection。这个系统存储过程大概会做如下事情:

  • 关闭游标
  • 清除临时对象,比如临时表
  • 释放锁
  • 重置Set选项
  • 重置统计信息
  • 回滚未提交的事务
  • 切换到连接的默认数据库
  • 重置Trace Flag

此外,根据BOL上的信息:

    "The sp_reset_connection stored procedure is used by SQL
Server to support remote stored procedure calls in a transaction. This stored
procedure also causes Audit Login and Audit Logout events to fire when a
connection is reused from a connection pool."

可以知道不能显式的在SQL Server中调用sys.sp_reset_connection,此外,这个方法还会触发Audit Login和Audit Logout事件。

一个简单的示例

下面我们通过一个简单的示例来看连接池的使用:

首先我分别使用四个连接,其中第一个和第二个连接之间有10秒的等待时间:

String ConnectionString = "data source=.\\sql2012;database=AdventureWorks;uid=sa;pwd=sasasa";SqlConnection cn1=new SqlConnection(ConnectionString);SqlCommand cmd1=cn1.CreateCommand();cmd1.CommandText="SELECT * FROM dbo.ABCD";cn1.Open();cmd1.ExecuteReader();cn1.Close();Response.Write("连接关闭时间:"+DateTime.Now.ToLongTimeString()+"<br />");System.Threading.Thread.Sleep(10000);SqlConnection cn2=new SqlConnection(ConnectionString);SqlCommand cmd2=cn2.CreateCommand();cmd2.CommandText="SELECT * FROM dbo.ABCD";cn2.Open();cmd2.ExecuteReader();cn2.Close();Response.Write("连接关闭时间:"+DateTime.Now.ToLongTimeString()+"<br />");SqlConnection cn3=new SqlConnection(ConnectionString);SqlCommand cmd3=cn3.CreateCommand();cmd3.CommandText="SELECT * FROM dbo.ABCD";cn3.Open();cmd3.ExecuteReader();cn3.Close();Response.Write("连接关闭时间:"+DateTime.Now.ToLongTimeString()+"<br />");System.Threading.Thread.Sleep(1500);SqlConnection cn4=new SqlConnection(ConnectionString);SqlCommand cmd4=cn4.CreateCommand();cmd4.CommandText="SELECT * FROM dbo.ABCD";cn4.Open();cmd4.ExecuteReader();cn4.Close();Response.Write("连接关闭时间:"+DateTime.Now.ToLongTimeString()+"<br />");

下面我们通过Profile截图:

我们首先可以看到,每一次Close()方法都会触发exec sp_reset_connection

此外,我们在中间等待的10秒还可以看到SP51是不断的,剩下几个连接全部用的是SPID51这个连接,虽然Ado.net Close了好几次,但实际上物理连接是没有中断的。

因此可以看出,连接池大大的提升了效率。

转载于:https://www.cnblogs.com/CareySon/archive/2012/11/15/2770991.html

Ado.net的连接池相关推荐

  1. ado.net mysql 连接池_ADO.NET中SQL Server数据库连接池

    实际上,大多数应用程序仅使用一个或几个不同的连接配置. 这意味着在执行应用程序期间,许多相同的连接将反复地打开和关闭. 为了使打开的连接成本最低,ADO.NET 使用称为连接池的优化方法. 连接池减少 ...

  2. ADO.NET中连接池状态的跟踪

    因为测试的时候用的都是小数据量数据,程序运行正常,但是到了客户那里,碰到才100多条的数据,居然提示我连接超时,让我百思不得其解.一时间不知道怎么跟踪好. 寻寻觅觅,终于找到了一个跟踪数据连接池状态的 ...

  3. ado.net mysql 连接池_ADO.NET数据库连接池的介绍 | 学步园

    摘录自MSDN: 建立池连接可以显著提高应用程序的性能和可缩放性.SQL Server .NET Framework 数据提供程序自动为 ADO.NET 客户端应用程序提供连接池.您也可以提供几个连接 ...

  4. ado.net mysql 连接池_ADO.NET数据连接池

    [IT168 技术文档]21世纪什么最贵?数据库连接.对于以数据库做数据存储基石的应用系统来说,数据库连接是整个系统中最珍贵的资源之一.数据库连接池是为了更有效地利用数据库连接的最重要措施.它对于一个 ...

  5. ADO.NET中在C/S模式中使用的连接池

    前几天同事问我一个问题,一种CS架构的程序,直接把SQL Server作为服务端,每个客户端直接连接数据库操作,如果客户端打开的数量过多时SQL Server的连接数将会特别高,数据库端形成性能瓶颈, ...

  6. python sqlserver api连接池_非常老的话题 SQLSERVER连接池

    非常老的话题 SQLSERVER连接池 写这篇文章不是说要炒冷饭,因为园子里有非常非常多关于SQLSERVER连接池的文章,但是他们说的都是引用MSDN里的解释 或者自己做一些测试试验一下连接池的性能 ...

  7. sqlserver连接池Min Pool Size

    今天遇到了关于Sql Server最大连接数(Max Pool Size)的配置问题 Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置 参考数据库 ...

  8. Ado.net连接池 sp_reset_connection 概念

    什么是连接池? 正常情况下,每次访问数据库都会打开和关闭,中断物理连接后需要再次进行物理连接.这样操作会浪费资源 使用连接池,主要的区别在于,不需要中断物理连接,即每次中断请求时spid还是存在! 原 ...

  9. 一种利用ADO连接池操作MySQL的解决方案(VC++)

    VC++连接MySQL数据库 常用的方式有三种:ADO.mysql++,mysql API ; 本文只讲述ADO的连接方式. 为什么要使用连接池? 对于简单的数据库应用,完全可以先创建一个常连接(此连 ...

  10. 浅谈如何更好的打开和关闭ADO.NET连接池

    MS提倡我们尽可能每次的在连接使用完成后就关闭:这样导致每次都要进行打开和关闭操作或用using(){-}写起代码比较麻烦,还有经常对池的操作似乎也带来一些性能上的问题:在Asp.net里一个WebF ...

最新文章

  1. ORACLE建视图 授权的 例子
  2. verycd重整——linux教程
  3. SZOJ 142 钦定
  4. Tungsten Fabric SDN — 软件项目编译与打包
  5. 数据结构与算法 | 二叉树的实现
  6. springboot配置定时任务及常用的cron表达式
  7. Python使用AES算法进行加解密
  8. DML、DDL、DCL区别
  9. php curl keep alive,php curl 保持长连接
  10. MongoDB复制集搭建主服务器模拟切换
  11. Python:命令安装pyQt5相关插件
  12. 每日一练蓝桥杯C语言:2020年真题题集(B组)
  13. win10计算机被网络设备发现,图文解决win10系统网络发现已关闭计算机和设备不见的方法...
  14. 调试EasyDarwin开源项目EasyCamera-HK接入海康IPCamera 摄像机所遇到的大坑
  15. SREng用法简要说明(如何获得日志/删启动项目/服务/驱动/BHO等)
  16. 数据分析小练手【5】 之 搜狗新闻(文本分析)
  17. w ndoWs8pE模式下载,天意PE迷你版V2011.9.9(天意PE系统)下载 - 下载吧
  18. EasyExcel删除模版Sheet页
  19. Anaconda3 python3.7安装Django稀里糊涂终于successful法
  20. 实时音视频数据传输协议介绍

热门文章

  1. 区块链 p2p点对点网络是什么
  2. thinkphp判断本地环境是否为SAE
  3. 基于springboot的高校后勤系统
  4. mysql更改安装路径命令_如何修改mysql的安装路径
  5. Leetcode之整数反转
  6. css 三种颜色表示,css颜色表示法
  7. Oracle 存储过程、存储函数 与原生 JDBC 调用
  8. mysql创建触发器怎么保存_如何创建使用mysql触发器?
  9. linux查看文件的编码格式的方法 set fileencoding PYTHON
  10. C++学习笔记 之 循环