Rickie Lee's blog

我是Rickie,毕业于上海交大,一直从事.NET平台上相关技术的开发、研究,多年服务于B2C 电子商务领域,包括前台、后台及仓库管理系统的业务流程分析、开发设计与实施。
现在正式加盟 - http://www.entlib.com 协力创建基于.NET的开源电子商务系统。 MSN:rickiechina@hotmail.com -- 欢迎交流!

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  394 随笔 :: 3 文章 :: 1421 评论 :: 129 引用

建立池连接可以显著提高应用程序的性能和可缩放性。SQL Server .NET Framework 数据提供程序自动为 ADO.NET 客户端应用程序提供连接池(MSDN)。

Opening a database connection is a resource intensive and time consuming operation. Connection pooling increases the performance of Web/windows applications by reusing active database connections instead of creating a new connection with every request. Connection pool manager maintains a pool of open database connections. When a new connection requests come in, the pool manager checks if the pool contains any unused connections and returns one if available. If all connections currently in the pool are busy and the maximum pool size has not been reached, the new connection is created and added to the pool. When the pool reaches its maximum size all new connection requests are being queued up until a connection in the pool becomes available or the connection attempt times out.

Connection pooling behavior is controlled by the connection string parameters. Please look into MSDN documents in the reference link if you want to know further information.

 

前面是关于连接池知识的一些基本介绍,下面的内容是重点,也是个人见解。因为没有这方面的文档资料参考或者佐证,所以请各位仔细思考和讨论(我不想误导大家)。

下面分2种情况进行讨论。

1Client端的windows form application通过ADO.Net直接访问后台Database


我认为在这种情况下,每一个Client端和Database之间都存在一个连接池。通过设置ConnectiongStringMax Pool SizeMin Pool Size属性来验证。

Max Pool Size = 5, Min Pool Size = 3, 通过SQL ServerSP_WHO2可以检测导如下结果:

启动1Client端的Windows form applicationapplicationSQL Server之间存在3connection

启动2Client端的Windows form applicationapplicationSQL Server之间存在6connection

启动3Client端的Windows form applicationapplicationSQL Server之间存在9connection

 

由此可见,每一个Client端和SQL Server之间都存在一个连接池,否则9connection已经超出了Max Pool Size的设定。

 

2Client端的application不直接通过ADO.Net来访问后台Database,而是通过IIS Server来同后台Database Server打交道。

至少有如下2种情况:

1Client通过IE访问部署在IIS中的web applicationweb application中的Data Access Class进一步访问后台Database Server.

2Client端的windows form application访问部署在IIS中的Remote ObjectRemote Object进一步访问后台Database Server.



下面进行同样的测试:通过设置ConnectiongStringMax Pool SizeMin Pool Size属性来验证。

Max Pool Size = 5, Min Pool Size = 3, 通过SQL ServerSP_WHO2可以检测导如下结果:

启动1Client端的Web form applicationapplicationSQL Server之间存在3connection

启动2Client端的Web form applicationapplicationSQL Server之间存在3connection

启动3Client端的Web form applicationapplicationSQL Server之间存在3connection

 

调用由IIS承载的Remote Object,结果类似。只是在未启动Client端之前,发现在Remote ObjectDatabase Server之间已经存在一个connection

 

由此可见,对同一个application而言,IIS ServerDatabase Server之间只有存在一个连接池,与Client端的多少没有关系。

 

3,连接池小节

根据上面的测试结果,显然第二种情况更有利于减少无用的连接数量,提高Database Server的性能。关于.Net Remoting技术及其性能问题,可以参考如下的Reference连接,这里就不讨论了。

另外,本文是个人关于连接池的一些见解,如果观点有不正确之处,希望不要误导各位。欢迎各位在此发表意见。同意的说赞同,不同意的请提出您的看法。谢谢。

 

Reference Links:

(1) MSDN, ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconconnectionpoolingforsqlservernetdataprovider.htm

(2) Microsoft .NET Remoting:技术概述, http://www.microsoft.com/china/MSDN/library/NetFramework/default.mspx

(3) 性能比较:.NET Remoting ASP.NET Web 服务, http://www.microsoft.com/china/msdn/archives/library/dnbda/html/bdadotnetarch14.asp

0
0
(请您对文章做出评价)
« 上一篇:将SqlHelper Class部署为Remote Object可行吗?
» 下一篇:重构(Refactoring)技巧读书笔记 之二
posted on 2004-10-02 06:00 Rickie 阅读(20470) 评论(32)  编辑 收藏 网摘 所属分类: 4.SQLServer技术, 1.Remoting技术

评论

#1楼 2004-10-02 11:27 wayfarer      
不错,学习!
  回复  引用  查看    

#2楼[楼主] 2004-10-02 11:54 Rickie      
wayfarer, Thanks. I've learned a lot from your blog.
  回复  引用  查看    

#3楼 2004-10-02 13:23 wayfarer      
@Rickie

呵呵^_^ 互相学习了,多交流哦。

  回复  引用  查看    

#4楼 2005-01-20 14:49 sunnykj
怎样查询当前application和SQL Server之间存在的connection数呢?
  回复  引用    

#5楼 2005-01-20 14:52 萝卜      
请问连接池是与数据库有关还是与开发语言有关?
  回复  引用  查看    

#6楼[楼主] 2005-01-20 15:10 Rickie      
To sunnykj:

You can execute SP_Who2 in SQL Query Analyzer form to check connections between client app. and SQL Server.

  回复  引用  查看    

#7楼[楼主] 2005-01-20 15:12 Rickie      
To 萝卜:
Connection pool is provided by .Net framework in .Net platform, which has no relationship with development languages and database Servers.

  回复  引用  查看    

#8楼 2005-01-21 12:00 萝卜      
谢谢您的回答,我想知道怎样能在连接结束后有效的把连接放回连接池呢通过connect.close好像不好用
  回复  引用  查看    

#9楼[楼主] 2005-01-21 13:24 Rickie      
To 萝卜:
It is recommended that you always close the Connection when you are finished using it in order for the connection to be returned to the pool. This can be done using either the Close or Dispose methods of the Connection object.

你可以通过调用Connection对象的Close或Dispose方法,将connection放回connection pool。

  回复  引用  查看    

#10楼 2005-03-04 14:40 听棠.NET      
我有个问题想请教一下啊:
如果我最大连接池是5个,那么,在我的程序中,每次访问,我都会使用New一个连接,然后Open,使用以后,然后Close,那么在每次New的时候,会不会创建连接,如果超过5个的话,还能New吗?
要是可以对连接进行控制的话,应该怎么控制,很简单,我现在每次使用数据库访问时,都会New并close,我是担心这样的效率是不是会很低啊,想在连接上提高效率,要怎么操作呢?

  回复  引用  查看    

#11楼[楼主] 2005-03-05 00:41 Rickie      
Q: 如果我最大连接池是5个,那么,在我的程序中,每次访问,我都会使用New一个连接,然后Open,使用以后,然后Close,那么在每次New的时候,会不会创建连接,?
A: 在每次New的时候,如果connection pool中有空闲的连接,则不会创建新连接,否则会创建。

如果超过最多连接数,还能发出New的请求,但是该请求会放入队列,直到connection pool中有空闲连接或连接请求超时。

  回复  引用  查看    

#12楼[楼主] 2005-03-05 00:43 Rickie      
Q: 要是可以对连接进行控制的话,应该怎么控制,很简单,我现在每次使用数据库访问时,都会New并close,我是担心这样的效率是不是会很低啊,想在连接上提高效率,要怎么操作呢?

A: 使用connection pool时,New并不一定会创建新的连接,如果connection pool中有空闲连接,直接拿来就用。

close也只是将连接放入connection pool,供后续请求使用。因此不会有效率问题。

  回复  引用  查看    

#13楼 2005-05-26 15:41 davidzhang
在windows2000、VS6中,垃圾回收机制会自动回收用过的连接,所以大多数的程序都没有链接关闭操作。如果将以前的ASP程序移动到windows2003的.Net平台下,是否需要对这些连接进行显示的关闭操作。
  回复  引用    

#14楼 2005-06-07 15:37 木头鱼
请问Connection 对象是在实例化的时候就被放入Connection Pool 还是在调用其Open方法的时候放入Connection Pool?
  回复  引用    

#15楼 2005-06-27 15:15 peepcn
是不是应该是这样的 第一种情况 每个clinet都用到自己的ado.net 而每个ado.net 都有一个连接池。 如果都通过一个应用服务器上的一个组件 这个组件包装一下ado.net 而其他client都只访问这个组件,就只有一个连接池了

我对.net Framework 不甚了解 我想请问一下com 里面可以利用ado.net 然后包装一个数据库访问中间件么 我听说ado.net只能用在托管c++里面 可能我概念都不是很清楚 请指教一下

  回复  引用    

#16楼 2005-08-17 11:50 defrost[未注册用户]
我认为如果在一段时间内,连接池内没有任何连接起用,连接池将把所有连接释放,返回给数据库!!这样能保证数据库的性能!!!


联系方式:
msn:defrostcn@yahoo.com.cn

  回复  引用    

#17楼 2005-08-18 09:30 齐国老兵      
defrost
当连接返回到池中时,将对它的创建时间和当前时间进行比较,如果时间间隔超过由 Connection Lifetime 指定的值(以秒为单位),则会毁坏该连接。在聚集配置中可以使用它来强制在运行服务器和刚联机的服务器之间达到负载平衡。
如果值为零 (0),则将使池连接具有最大的超时期限。默认值为0

  回复  引用  查看    

#18楼 2005-08-18 19:26 defrost[未注册用户]
楼上说的我没有做过实验,我没有那么精确的数据.但结果肯定是对的,连接池中的连接最终会被释放掉的.但释放时机我没有确定.我跟踪SQL事件时,连接池中的连接在没有任何响应时会被释放掉,这是肯定的.
  回复  引用    

在这里我先佩服一下楼主,以后碰到问题希望楼主能够帮忙,先谢谢!
  回复  引用    

连接池是ado.net负责管理的,所以对于第一种情况,由于服务器端只存在后台数据库而没有.net程序,肯定是一个客户端一个连接池。
至于defrost 所说的连接池内没有任何连接起用的情况,如果设置了Connection Lifetime的话才对,否则在默认情况下只有当你的应用程序退出时连接池才销毁。

个人看法。希望没有误导人。

  回复  引用    

#21楼 2005-10-18 09:42 kakaka[未注册用户]
都是关闭数据库,放回连接池,SqlConnection.Close()和.Dispose()
有什么本质区别?用哪个更好?

  回复  引用    

sqlconnection.close和.dispose的相同地方是:
dispose肯定调用了close,所以close里面有做的事情,dispose都包括

dispose还做了其他的资源的释放,这样在GC第一次回收的时候,省却了dispose的步骤,加快了内存资源的回收速度。
如果没有调用dispose,GC将在第一次回收先做dispose。

如果程序频繁做new sqlconnection(),然后很快就做close并且不再使用这个connection(例如一些com+/asp.net/web service的程序),而且又不做dispose,那么随着这个程序被多次调用,被分配但未能尽快释放的系统资源(通常是内存)会有很多,GC被迫回收的次数也相应增多,系统的整体效率就会变低(GC回收的时候是所有.net程序都暂停,等GC回收跑完才可以继续,造成其他程序也受到影响)。所以对于这种情况,做dispose好。
但如果其他情况,例如Winforms的client,那么没有所谓。

  回复  引用    

How to use conection pool in asp web services?
  回复  引用    

请教一下:
我的程序是/asp.net/web service的,每隔一段时间(也许是一两周吧,不确定)就会出现此错误,说连接池已满:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

请问如何解决此问题呢?是因为我每次用完connection后没有dispose,只是close的原因吗?盼赐教!多谢!!

  回复  引用    

#25楼 2006-03-15 18:15 仁面寿星      
我想请教一个问题:
我使用IDATAREADER,每次都关闭,但是连接并不关闭,然后我又用同样的连接字符串去实例化新的连接,开始,几次操作后,我在SQLSERVER中发现我有很多个sleep的数据库连接,为什么会这样?

因为IDATAREADER是持续连接的,我就怀疑是这点造成的,于是改成DataTable,测试后,还是有很多sleep的原因

  回复  引用  查看    

我在一个页面里有十个查询,一旦对这个页面请求的数据一多的时候就出现
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

Source Error:


Line 18: strSQL="select top 6 * from news where Appearance=1 and NewsType=1 order by id desc";
Line 19: da = new SqlDataAdapter(strSQL,strConn);
Line 20: da.Fill(ds,"news");
Line 21: DataGrid1.DataSource=ds;
Line 22: DataGrid1.DataBind();


  回复  引用    

#27楼 2007-02-08 23:32 ma [未注册用户]
@wayfarer

  回复  引用    

#28楼 2007-11-23 18:49 xuexi[未注册用户]
看了您的,受益匪浅呀,不过我想问一下连接池设多大合适了!
  回复  引用    

#29楼 2008-05-30 10:54 求知无傲      
虽然看不太懂,但是还是要支持一把。
  回复  引用  查看    

#30楼 2008-12-10 10:22 不见不散      
受益匪浅。感谢楼主分享。
  回复  引用  查看    

#31楼 2009-03-28 05:59 真没劲      
请问一个,一个IIS上部署了多个Web App,分布在多个IIS Applicaion Pool,请问在IIS Server上存在多少个.Net Connection Pool?
  回复  引用  查看    

如果想解决楼主说的第一种情况,则应该在所有client和server之间建立一个代理程序,甚至是单独的代理服务器。

所有的client端都连到代理服务器,把请求发送给代理服务器,代理服务器根据一定的算法将这些请求放入一个队列,然后由代理服务器上的数据查询程序去直接和db server进行通信,并将查询结果依次返回给对应的client端。

这个是简单的解决办法。

典型的应用例子就是商场里的收银机。如果是个大型商场,每秒进行的交易是很客观的,如果采用收银机直接跟db server进行通信、计算,db server很可能会经常崩溃。

my QQ : 146646

  回复  引用