Dispose了,就必须再Create一次 以下是相关知识点: 1.SqlConnection conn = new SqlConnection(strConnection)时,如果原来的连接已经关闭,此时需要开启一个新连接时,只要strConnection与上次的一样,就会又从连接池中取回原来的对象。Close时,SqlConnection的实例并不会被释放,它仅仅是被关闭了,并放置到了另一个地方,当下次需要时,会再次取出来。这样可以避免创建实例的开例。哈,不过,我认为这样的意义不是很大,只是.NET框架提供的一种管理优化机制而已(因为最消耗时间的还是Open与Close) 连接池允许应用程序从连接池中获得一个连接并使用这个连接,而不需要为每一个连接请求重新建立一个连接。一旦一个新的连接被创建并且放置在连接池中,应用程序就可以重复使用这个连接而不必实施整个数据库连接创建过程。 当应用程序请求一个连接时,连接池为该应用程序分配一个连接而不是重新建立一个连接;当应用程序使用完连接后,该连接被归还给连接池而不是直接释放。 数据库连接池中可能存在着多个没有被使用的连接一直连接着数据库(这意味着资源的浪费)。 使用连接池的最主要的优点是性能。创建一个新的数据库连接所耗费的时间主要取决于网络的速度以及应用程序和数据库服务器的(网络)距离,而且这个过程通常是一个很耗时的过程。而采用数据库连接池后,数据库连接请求可以直接通过连接池满足而不需要为该请求重新连接、认证到数据库服务器,这样就节省了时间。 包含在ADO.NET中的每个.NET数据提供程序都可实现连接池。 每一个连接池都与一个独立的连接字符串及其事务上下文关联。每次打开一个新的连接,数据提供者会尝试将指定的连接字符串与连接池的字符串进行匹配。如果匹配失败,数据提供者创建一个新的连接并将它加入连接池。连接池被创建之后,除非进程结束,否则不会被拆除。有人认为这种处理方式会影响性能,其实不然,维护一个不活动的或者空的连接池不需要多少开销。 连接池创建之后,系统会创建一些连接对象并将它们加入连接池,直至达到额定的最小连接对象数量。以后,系统会根据需要新建和加入连接对象,一直到达最大连接对象数量限额为止。如果程序请求一个连接对象时没有空闲的连接对象可用,且连接池里面的对象数量已达到上限,则请求被放入队列,一旦有连接被释放回缓冲池就立即取出使用。 注意:如果是并发访问里,一个连接正在被使用,而此时又启动了另一个进程或线程,则也会创建一个新的连接并放入连接池之中。只有第一次调用关闭后,第二次再次调用的时候,如果是相同的连接字符串,才会直接调用连接池中的连接。 关闭一个连接时,连接对象被返回给连接池以便重用,但这时实际的数据库连接并未被拆除。如果禁用了连接池,则实际的数据库连接也被关闭。这里必须强调的一点时,连接对象使用完毕后应当显式关闭并将它返回给连接池,不要依靠垃圾收集器来释放连接。 调用Close或Dispose方法可以将连接释放回连接池。只有当生存期结束或出现严重错误时,连接对象才会被从连接池删除。 对于.NET应用程序而言,默认为允许连接池。(这意味着你可以不必为这件事情做任何的事情)当然,如果你可以在SQLConnection对象的连接字符串中加进Pooling=true;确保你的应用程序允许连接池的使用。 ADO.NET默认为允许数据库连接池,如果你希望禁止连接池,可以使用如下的方式: 注意:在达到最小连接对象数量之前,是会不断创建新的连接对象的,另外,最大连接数量,实际上是指出了连接的并发数。 ====================== static不保证你在多线程模式下仍是线程安全的,但总的来说,多一个连接的消耗在这里并不会造成什么影响,但有可能造成运行时的异常。将sqlConnection设置成static,一般情况下,不会有什么影响。 =================================== ADO.Net连接池和连接字符串详细说明 当然如果我地程序需要不定时地打开和关闭连接,(比如说 ASP.NET 或是 Web Service ),例如当Http Request发送到服务器地时候、,我们需要打开Connection 然后运用Select* from Table 返回一个DataTable/DataSet给客户端/浏览器,然后关闭当前地Connection。那每次都Open/Close Connection 如此地频繁操作对于整个系统择定确定就成了一种浪费。 ADO.Net Team就给出了一个比较好地解决方法。将先前地Connection保存起来,当下一次需要打开连接地时候就将先前地Connection 交给下一个连接。这就是Connection Pool。 - Connection Pool 如何工作地? 当程序执行到Connection.close() 地时候。如果Pooling 为True,ADO.net 就把当前地Connection放到Connection Pool并且维护与数据库之间地连接。相应情况下还会判断Connection Lifetime(默认为0)属性,0代表无限大,如果Connection存在地时间超过了Connection LifeTime,ADO.net就会关闭地Connection相应情况下断开与数据库地连接,而不是重新保存到Connection Pool中。(这个设置重点用于群集地SQL 数据库中,达到负载平衡地目地)。如果Pooling指定为False,则直接断开与数据库之间地连接。 然后当下一次Connection.Open() 执行地时候,ADO.Net就会判断新地ConnectionString与原先保存在Connection Pool中地Connection地connectionString是否一致。(ADO.Net会将ConnectionString转成二进制流,所以也就是说,新地ConnectionString与保存在Connection Pool中地Connection地ConnectionString必须完全一致,即使多加了一个空格,或是修改了Connection String中某些属性地次序都会让ADO.Net认为这是一个新地连接,而从新创建一个新地连接。所以如果您运用地UserID,Password地认证方式,修改了Password也会导致一个Connection,如果运用地是SQL地集成认证,就需要保存两个连接运用地是同一个)。然后ADO.net需要判断当前地Connection Pool中是否有可以运用地Connection(没有被其他程序所占用),如果没有地话,ADO.net就需要判断ConnectionString设置地Max Pool Size (默认为100),如果Connection Pool中地所有Connection没有达到Max Pool Size,ADO.net则会再次连接数据库,创建一个连接,然后将Connection返回给程序。如果已经达到了MaxPoolSize,ADO.net就不会再次创建任何新地连接,而是等待Connection Pool中被其他程序所占用地Connection释放,这个等待时间受SqlConnection.ConnectionTimeout(默认是15秒)限制,也就是说如果时间超过了15秒,SqlConnection就会抛出超时错误(所以有时候如果SqlConnection.open()方法抛出超时错误,一个可能地原因就是没有及时将原先地Connnection关闭,相应情况下Connection Pool数量达到了MaxPoolSize。)如果有可用地Connection,从Connection Pool 取出地Connection也不是直接就返回给程序,ADO.net还需要检查ConnectionString地ConnectionReset属性(默认为True)是否需要对Connection 最一次reset。这是由于,原先从程序中返回地Connection可能已经被修改过,比如说运用SqlConnection.ChangeDatabase method 修改当前地连接,此时返回地Connection可能就已经不是连接当前地Connection String指定地Initial Catalog数据库了。所以需要reset一次当前地连接。当然由于所有地额外检查都会增大ADO.net Connection Pool 对系统地开销。
Pooling (true) Connection Lifetime (0) Enlist (True) Max Pool Size (100) Min Pool Size (0) ConnectionReset (True) 附带地提一下,在ADO.net 2.0 地世界中,修改SqlConnectionString 我们可以运用SqlConnectionStringBuilder类来完成
1)那么及时地调用.dispose()真地这么重要么,如果一个对象超出了生存空间,在.net中不是会自动被GC(垃圾回收器)自动清理地么? 这个问题其实是由于GC导致地,.net中运用地GC,他对于工作并不像我们这样勤奋。GC只有当外界环境非常恶劣地时候(没有足够地内容分配地时候)他才会动手打扫卫生(清理不运用地对象)。所以对于Connection 即使超出了变量地生命周期,它可能还没有被GC干掉。依旧未将Connection返回给Connection Pool。 2)Dispose 到底做了些什么? protected override void Dispose(bool disposing) 3)如果运用using 是必需地,那么如果程序结构导致我无法运用using(){}来包裹我地Connection,比如说我地Connection是同一个help类返回地,那我又怎么办呢? 这是一个经常遇到地问题。在这样地环境中,我们无法将整个connection包裹在一个connection中。
如果您地项目是ASP.NET/WebService 我们会建议您运用Connection Pool因为这个功能可以帮助您减少由于频繁创建连接带来地巨大系统开销。 如果您地系统是一个C/S模型结构,我们会不建议您运用Connection Pool,这是由于一般而言,在C/S这样地模型中,每一个用户均为运用自己地用户名密码去连接后台数据库,运用地均为不同地Connection String,根本不会出现频繁出现打开/关闭数据库连接地问题,实际上在C/S模型中,您可以一直使一个Connection维护open地关闭,而不Close,这样更可以提高您系统地性能,不会由于Connection Pool地额外检查而带来系统资源地消耗,相应情况下也不必担心一直打开地Connection长时间地占用了连接,导致其他地连接无法从connection pool 及时获取到。(因为您根本就不需要运用到connection pool)。 Hope this helps. 另外地一点备住: |
数据库连接池
最新推荐文章于 2024-10-11 17:04:33 发布
dispose与close()的区别
2009年08月11日 星期二 17:07