数据访问技术系列课程 笔记(4) 使用连接池
连接池的概念
1)连接池是一个进程
多个连接是在一个进程里面存储、管理的。这个进程保存所有的连接,当我们打开连接,如果有未用连接可用,则返回该连接。如果池中的连接都用完了,则创建一个新的连接保存到连接池。而但我们关闭连接的时候,连接池里面并不关闭连接,而是返回连接池中并标记为可重用的状态,等待重新连接直到等待超时。再次打开连接的时候,我们就可以重用上次的连接。如果在这个时间内没有连接请求(打开连接),这个数据库连接将被关闭,并从连接池中移除这个连接实例。如果池中连接到达了最大连接数,请求进入等待队列直到空闲连接可用。如果在可获取连接对象之前超时期限已过(由 Connect Timeout 连接字符串属性来决定),则将出错。
2)该进程保存连接并使其处于活动状态,使连接可以被重复使用
应用程序访问底层的数据源的时候是通过OS的数据访问组件或者说Sql Client数据访问提供程序进行访问的。都是通过系统提供的组件去访问数据库服务器的数据库的。连接是通过这些组件建立的,连接池是在这些组件之上的,它存在于应用程序的进程里面。因此需要重用连接,就是在这一个进程里面重用。例如:两个WinForm程序在不同的计算机上,他们同时连接一个数据库服务器,这个时候,连接池就没办法起作用,因为连接池是一个进程里面。这时候,我们可以在数据库服务器上层搭建一个Web Service,而Web Service 和数据库服务器之间使用的是连接池,数据库服务器的压力就会小。
如果没有连接池
1)连接到数据源
– 建立物理通道(例如套接字或命名管道)
– 与服务器进行初次握手
– 分析连接字符串信息
– 由服务器对连接进行身份验证
– 运行检查以便在当前事务中登记(连接的环境是不是分布式事务)
另:不仅是连接池,还有使用的比较多的对象,我们也可以将之放在对象池,以便下次使用。
连接池的作用
1)通过数据库连接池,应用程序可以重用池中现有的连接中现有的连接,而不必反复与数据库建立新的连接。
2)使用连接池可显著提高应用程序的可伸缩,因为有限数量的数据库连接可以为数量大得多的客户端提供服务。例如:数据库应用里面,上万的用户可能只需要少量的连接,因为客户端不可能同时并发的大量的访问数据库。故少量的连接可以支持大量的服务,提高程序的可伸缩性。
3)同时,由于可以节省建立新连接所需的大由于可以节省建立新连接所需的大量时间,使用连接池还能够改善性能。
4)连接池对于应用程序来说是透明的,例如:conn.Open() 和 conn.Close()。
连接池的工作过程
1) Pooling 参数为true 时(默认),连接池启用连接池启用
在应用程序执行的环境里面会创建一个存储区域专门来存储需要使用的连接。
2) 两个连接的连接字符串相同时,被放置在一个连接池中。
3) 两个连接的连接字符串不同时,被放置在不同的连接池中。
例如:一个winform程序,可能需要连接多个数据库,就会造成应用程序里面会有多个连接池,从服务器的角度来讲,连接的数量也是比较多的,一个应用程序可能有多个应用程序域,连接池是属于一个应用程序域。一个应用程序域可以有多个连接池。一个连接字符串对应一个连接池。
4) 连接被Close时,连接被返回到连接池中以备重用(当连接池中的连接长时间不活动或者超出指定的生存期(Connection Lifetime )时,将被移除。在聚集配置中可以使用Connection Lifetime来强制在运行服务器和刚联机的服务器之间达到负载平衡。只有在尝试与服务器进行通讯后,才可以检测到这种情况。如果发现某连接不再连接到服务器,则会将其标记为无效。对象池管理程序会定期扫描连接池,以查找已被释放到池中并标记为无效的对象。找到后,这些连接将被永久移除。)
5) 连接被Dispose时,连接被彻底删除
6) 连接池最后一个连接被Close 时,连接池被删除
注:通常开始的时候,设置连接池为true。并发执行的连接的数量要根据实际情况而定。连接池满的时候,是无法连接的。
对于一个连接,若要成为可用连接,该连接当前必须未被使用,具有匹配的事务上下文或者不与任何事务上下文相关联,并且具有与服务器的有效链接。
控制SQL Server连接池
1)SQL Server 连接池有关的连接字符串变量
参数 |
含义 |
默认值 |
备注 |
Connection Lifetime |
连接生存周期 |
0 |
默认为0表示:连接永远不会从池中被自动移走 |
Connection Reset |
连接重置 |
True |
|
Enlist |
登记 |
True |
|
Max Pool Size |
最大池大小 |
100 |
连接池的最大连接数 |
Min Pool Size |
最小池大小 |
0 |
连接池被创建,则会创建指定的最小连接数量的连接 |
Pooling |
池 |
True |
是否启用连接池 |
控制OLE DB连接池
1)默认连接池功能是激活的,在OLE DB 连接中使用
2)如要禁用OLE DB 连接池,在连接字符串中指定“OLE DB Services= -4” ,代码如下代码如下
Dim cnNorthwind As New OleDbConnection()
cnNorthwindcnNorthwind.ConnectionStringConnectionString == _
"Provider=SQLOLEDB;" & _
"Data Source=London;" &
"Integrated Security=SSPI;" & _
"OLE DB Services=-4;" & _
"Initial Catalog=Northwind;"
使用连接池
1)连接是通过连接字符串上的完全匹配算法进行池化的。
该算法会使连接池与连接中的字符串相关联。当新连接打开时,如果连接字符串不精确匹配现有池,则将创建一个新池。
2)池机制甚至对名称-值对之间的空格也敏感。
关闭连接(使连接返回池中)
1)使用完连接后,立即显示关闭连接
2)不要在类的Finaliz方法(此方法不是自动调用的)中关闭连接
– 因为它在垃圾回收时才会执行
– 很有可能会造成连接池已满
3)DataAdappter前显式打开的连接不会自动关闭(在使用DataAdappter之前如果显示的打开了连接必须在使用完之后显示关闭,自动打开的会自动关闭)
4)未显式关闭的连接将不会添加或返回到池中。
连接池的驻留
1) 如果MinPoolSize 在连接字符串中未指定或指定为零,池中的连接将在池中一段时间不活动后关闭。
2) 如果指定的MinPoolSize大于零,在 AppDomain 被卸载并且进程结束之前,连接池不会被破坏。
3) 非活动或空池的维护只需要最少的系统开销。
清除连接池
1) ClearAllPools
– 清除给定提供程序的连接池。
2) ClearPool(SqlConnection)
– 清除与特定连接关联的连接池。
– 如果在调用时连接正在使用,将进行相应的标记。连接关闭时,将被丢弃,而不是返回池中。
池碎片
1) 池碎片是许多Web 应用程序中序中的一个常见问题,应用程序可能会创建大量在进程退出后才会释放的池。这样,将打开大量的连接,占用许多内存,从而影响性能。
– 因为集成安全性产生的池碎片
– 因为许多数据库产生的池碎片
事务支持
1) 连接是根据事务上下文来从池中取出并进行分配的。
– 除非在连接字符串中指定了Enlist = false,否则,连接池将确保连接在Current 上下文中登记。
– 当连接通过登记的System.Transactions 事务关闭并返回到池中时,连接将被保留,以便下次使用同一System.Transactions 事务请求该连接池时务请求该连接池时,可返回同一连接(如果该连接可用)。
– 如果该连接不可用,则会打开新连接。
– 如果该事务没有可用连接,在该连接打开时,将自动注册该连接。
2) 当连接关闭时,它将被释放回池中,并根据其事务上下文放入相应的子部分。
– 因此,即使分布式事务仍然挂起,仍可以关闭该连接而不会生成错误。
– 这样,就可以在随后提交或中止分布式事务。
– 当连接返回到池中时,将对它的创建时间和当前时间进行比较,如果时间间隔超过由 Connection Lifetime 指定的值(以秒为单位),则会毁坏该连接。在聚集配置中可以使用它来强制在运行服务器和刚联机的服务器之间达到负载平衡。如果值为零 (0),则将使池连接具有最大的超时期限。
事务专有池
1) 连接池被划分为多个事务专有池和一个与当前尚未在事务中登记的连接对应的池。
2) 对于与特定事务上下文关联的线程,会返回相应池回相应池(该池包含在该事务中登记的连该池包含在该事务中登记的连接)的连接。
3) 这使得使用已登记的连接成为一个透明的过程。
使用池对象管理连接池
1) 作为分布式开发人员,鼓励禁用OLE DB 资源池和//或ODBC 连接池,并使用COM+ 对象池作为池化数据库连接的技术。
2) 这有两个主要原因这有两个主要原因:
– 池大小和阈值可以明确的配置(在COM+ 目录中)。
– 性能得到改善。池对象方法的性能比本机池高50%。
3) 如果您使用的是如果您使用的是OLE DB .NET数据提供程序,您可能需要考虑使用COM+ 对象池,以便充分利用卓越的配置和改善的性能。如果您为此目的开发池对象,则必须禁用OLE DB 资源池和自动事务登记(例如,通过在连接字符串中包含通过在连接字符串中包含"OLE" DB Serviices=-4)。您必须在自己的池对象实现中处理事务登记。
4) 对于SQL Server .NET 数据提供程序来说,它在内部使用池机制,所以您不再需要开发自己的对象池机制(在使用该提供程序时)。因此,您可以避免执行与手动事务登记相关联的复杂任务。
监控连接池
1) SQL Server 事件探查器
2) 性能监视器
可以在“.NET CLR 数据”性能对象下的“性能监视器”中访问连接池计数器。可访问:
a)当前池连接和非池连接的数目
b)当前所有池中与特定进程关联的连接的数目
c)当前与特定进程关联的池的数目
d)自特定进程开始以来所有池中的连接数峰值。请注意:此计数器只有在与特定进程实例关联时才可用。
e)打开连接的尝试因任何原因而失败的总次数
3) 编程方式
4) 使用sp_who或sp_who2存储过程