以前在做JSP时接触过数据库连接池,现在学了.net想学习下.net中怎么使用连接池,经过一番搜索,总结如下:
数据库链接是一种危险的、昂贵的、有限的资源,特别是在多层Web应用程序中。你必须正确管理你的链接,因为你的方法将极大的影响应用程序的整体升级性。高性能应用程序与使用中的数据源保持最短时间的连接,并且利用性能增强技术,例如连接池。连接池用于ODBC 的 SQL
Server、OLE
DB 和 .NET 框架数据提供程序隐式缓冲连接。通过在连接字符串中指定不同的属性值,可以控制连接池的行为。
连接池概述
数据库链接池使应用程序能够重用池中的现有链接,而不是重复地建立对数据库的链接。这种技术将极大地增加应用程序的可扩展性,因为有限的数据库链接可以为很多的客户提供服务。此技术也将提高性能,因为能够避免用于建立新链接的巨大时间。
具体来说,大多数 ADO.NET 数据提供程序使用连接池,以提高围绕 Microsoft 断开连接的 .NET 结构构建的应用程序的性能。应用程序首先打开一个连接(或从连接池获得一个连接句柄),接着运行一个或多个查询,然后处理行集,最后将连接释放回连接池。如果没有连接池,这些应用程序将花费许多额外时间来打开和关闭连接。
下面将以SQL
Server .NET
Framework 数据提供程序连接池为例来说明连接池的一些性能和用法。(另外还有ODBC
.NET
Framework 数据提供程序连接池、OLE
DB .NET
Framework 数据提供程序连接池。)
池的创建和分配
当连接打开时,将根据一种精确的匹配算法来创建连接池,该算法会使连接池与连接中的字符串相关联。每个连接池都与一个不同的连接字符串相关联。当新连接打开时,如果连接字符串不精确匹配现有池,则将创建一个新池。
在以下示例中,将创建三个新的 SqlConnection 对象,但只需要使用两个连接池来管理这些对象。请注意,第一个和第二个连接字符串的差异在于为 Initial
Catalog 分配的值。
SqlConnection conn = new
SqlConnection();
conn.ConnectionString = "Integrated
Security=SSPI;Initial Catalog=northwind";
conn.Open();
// Pool A is created.
SqlConnection conn = new
SqlConnection();
conn.ConnectionString = "Integrated
Security=SSPI;Initial Catalog=pubs";
conn.Open();
// Pool B is created because the connection
strings differ.
SqlConnection conn = new
SqlConnection();
conn.ConnectionString = "Integrated
Security=SSPI;Initial Catalog=northwind";
conn.Open();
// The connection string matches pool
A.
连接池一旦创建,直到活动进程终止时才会被毁坏。非活动或空池的维护只需要最少的系统开销。
在使用SQL Server
.NET数据供应器链接池时,必须清楚:
链接是通过对链接字符串精确匹配的法则被池化的。池化机制对名称-值对间的空格敏感。例如,下面的两个链接字符串将生成单独的池,因为第二个字符串包含了一个额外的空字符。
SqlConnection conn = new
SqlConnection("Integrated
Security=SSPI;Database=Northwind");
conn.Open(); // Pool A is
created
SqlConmection conn = new
SqlConnection("Integrated Security=SSPI ;
Database=Northwind");
conn.Open(); // Pool B is created (extra
spaces in string)
连接的添加
连接池是为每个唯一的连接字符串创建的。当创建一个池后,将创建多个连接对象并将其添加到该池中,以满足最小池大小的要求。连接将根据需要添加到池中,直至达到最大池大小。
当请求 SqlConnection 对象时,如果存在可用的连接,则将从池中获取该对象。若要成为可用连接,该连接当前必须未被使用,具有匹配的事务上下文或者不与任何事务上下文相关联,并且具有与服务器的有效链接。
如果已达到最大池大小且不存在可用的连接,则该请求将会排队。当连接被释放回池中时,连接池管理程序通过重新分配连接来满足这些请求。对 Connection 调用 Close 或 Dispose 时,连接被释放回池中。
连接的移除
如
果连接生存期已过期,或者连接池管理程序检测到与服务器的连接已断开,连接池管理程序将从池中移除该连接。请注意,只有在尝试与服务器进行通信后,才可以
检测到这种情况。如果发现某连接不再连接到服务器,则会将其标记为无效。连接池管理程序会定期扫描连接池,查找已释放到池中并标记为无效的对象。找到后,
这些连接将被永久移除。
如果存在与已消失的服务器的连接,那么即使连接池管理程序未检测到已断开的连接并将其标记为无效,仍有可能将此连接从池中取出。当发生这种情况时,将生成异常。但是,为了将该连接释放回池中,仍必须将其关闭。
选择池容量
能建立最大极限对于管理几千用户同时发出请求的大型系统来说是非常重要的。你需要监视链接池及应用程序的性能,以确定系统的最优池容量。最优容量还要依赖于运行SQL
Server的硬件。
在开发期间,也许需要减小默认的最大池容量(目前是100)以帮助查找链接泄漏。
如果设立了最小池容量,那么当池最初被填充以达到该值时,会导致一些性能损失,尽管最初链接的几个客户会从中受益。注意,创建新链接的过程被序列化了,这就意味着当池最初被填充时,服务器无法处理同时发生的请求。
监视链接池化
要监视应用程序对链接池化的应用情况,可以使用随SQL
Server发行的Profiler工具,或随微软Windows
2000发行的性能监视器。
要利用SQL Server
Profiler 监视链接池化,操作如下:
1. 单击开始,指向程序,指向Microsoft
SQL
Server,然后单击Profiler运行Profiler。
2. 在文件菜单中,指向新建,然后单击跟踪。
3. 提供链接内容,然后单击确定。
4. 在跟踪属性对话框中,单击事件标签。
5. 在已选事件类别列表中,确保审核登录和审核登出事件显示在安全审核下面。
6. 单击运行开始跟踪。在链接建立时,将会看到审核登录事件;在链接关闭时看到审核登出事件。
要通过性能监视器监视链接池化,操作如下:
1. 单击开始,指向程序,指向管理工具,然后单击性能运行性能监视器。
2. 在图表背景中右击,然后单击增加计数器。
3. 在性能对象下拉列表框中,单击SQL
Server:通用统计。
4. 在出现的列表中,单击用户链接。
5. 单击增加,然后单击关闭。
连接池FAQ
1.
何时创建连接池?
当第一个连接请求到来时创建连接池;连接池的建立由数据库连接的连接字符创来决定。每一个连接池都与一个不同的连接字符串相关。当一个新的连接请求到来时如果连接字符串和连接池使用的字符串相同,就从连接池取出一个连接;如果不相同,就新建一个连接池。
2.
何时关闭连接池?
当连接池中的所有连接都已经关闭时关闭连接池。
3.
当连接池中的连接都已经用完,而有新的连接请求到来时会发生什么?
当连接池已经达到它的最大连接数目时,有新的连接请求到来时,新的连接请求将放置到连接队列中。当有连接释放给连接池时,连接池将新释放的连接分配给在队列中排队的连接请求。你可以调用close和dispose将连接归还给连接池。
4.
我应该如何允许连接池?
对于.NET应用程序而言,默认为允许连接池。(这意味着你可以不必为这件事情做任何的事情)当然,如果你可以在SQLConnection对象的连接字符串中加进Pooling=true;确保你的应用程序允许连接池的使用。
5.
我应该如何禁止连接池?
ADO.NET默认为允许数据库连接池,如果你希望禁止连接池,可以使用如下的方式:
1)
使用SQLConnection对象时,往连接字符串加入如下内容:Pooling=False;
2)
使用OLEDBConnection对象时,往连接字符串加入如下内容:OLE DB Services=-4;
理论上明白了,再看下面的你就会懂得它的用法了,试试看:
连接池如何工作
连接池中包含打开的可重用的数据库连接。在同一时刻同一应用程序域中可以有多个连接池,但连接池不可以跨应用程序域共享。注意:一个连接池是通过一个唯一的连接字符串来创建。连接池是根据第一次请求数据库连接的连接字符串来创建的,当另外一个不同的连接字符串请求数据库连接时,将创建另一个连接池。因此一个连接字符中对应一个连接池而不是一个数据库对应一个连接池。如以下代码所示
代码1
// 新建一个连接池SqlConnection sqlConnection = new
SqlConnection();sqlConnection.ConnectionString =
"Server=localhost;Database=test;User
ID=joydip;Password=joydip;Trusted_Connection=False";sqlConnection.Open();
代码2
// 因为连接字符串不同,新建另一个连接池SqlConnection conn = new
SqlConnection();sqlConnection.ConnectionString =
"Server=localhost;Database=test;User
ID=test;Password=test;Trusted_Connection=False";sqlConnection.Open();
代码3
// 因为连接字符串与代码1相同,不再创建连接池.SqlConnection conn = new
SqlConnection();sqlConnection.ConnectionString =
"Server=localhost;Database=test;User
ID=joydip;Password=joydip;Trusted_Connection=False";sqlConnection.Open();
当有新的数据库连接请求到来时,连接池中连接进行了响应而不用创建一个新的数据库连接,也就是说数据库连接可以被重用,而不需要重新新建连接。因此这提高了应用程序的效率和可伸缩性。当你在应用程序中关闭一个打开的数据库连接时,该连接返回到连接池中等待重新连接直到等待超时。在这个时间内等待同一数据库相同连接信息的连接请求。如果这个时间内没有连接请求,这个数据库连接将被关闭,并从连接池中移除这个连接实例。
当一个新的连接池创建后,数据库连接被添加到池中,连接池和池中的连接立即可被使用。连接池中将填满连接字个串中指定的最小连接数量的连接。连接池中连接在长时间不活动或超出指定的生存期时将被移除。
连接池由连接池管理器维护。当后续的连接请求到来,连接池管理器在连接池中寻找可用的空闲的连接,如果存在就交给应用程序使用。以下描述了当一个新的连接请求到来时连接管理器如何工作
· 如果有未用连接可用,返回该连接
· 如果池中连接都已用完,创建一个新连接添加到池中
· 如果池中连接已达到最大连接数,请求进入等待队列直到有空闲连接可用
通过连接字符串中传递的参数可以控制连接池。基本的参数包括:
· Connect Timeout
· Min Pool Size
· Max Pool Siz
· Pooling
为了有效的使用连接池,记住数据库操作完成后马上关闭连接,这样连接才能返回连接池中。
提高连接池性能
我们应该在最晚时刻打开连接并在最早时刻释放连接,即在使用完成后立即释放。数据库连接应该在真正请求数据时才打开,而不应在使用之前就请求连接,这会减少池中可用连接的数量,因此有害于连接池的操作及应用程序性能。数据库连接应使用完成后立即释放,这能促进连接池更好的使用,因为连接可以返回池中被重新使用。以下代码展示如何在应用程序中有效地打开和关闭连接
代码4
SqlConnection sqlConnection = new
SqlConnection(connectionString);try{ sqlConnection.Open(); //Some
Code} finally{
sqlConnection.Close();}代码4可以使用”using”关键字进一步简化如以下代码所示
代码5
using(SqlConnection sqlConnection = new
SqlConnection(connectionString)){ sqlConnection.Open(); //Some
Code}
注:以上代码5中的”using”关键字将隐含地生成try-finally块
以下列举了更好地使用连接池的几个可参考要点
1) 在需要使用时才打开连接,并在完成操作后马上关闭
2) 在关闭连接时先关闭相关用户定义的事务
3) 确保维持连接池中至少有一个打开的连接
4)在使用集成身份验证的情况下避免使用连接池
连接池可以通过以下途径进行监控
· 使用sp_who或sp_who2存储过程
· 使用SQL Server的Profiler
|