知道现在编程什么是最宝贵的?数据库连接,它其实是很耗费资源的。这里我们就连接池这个问题我们来一起讨论讨论吧。数据库连接池是为了更有效地利用数据库连接的最重要措施。它对于一个大型的应用系统的性能至关重要,特别是Web应用。ADO.NET Data Provider(以下简称Data Provider)会帮我们管理连接池,所以有人说使用连接池就像游儿童池一样轻松。但并不是说有了Data Provider程序员就万事无忧的,不正确地使用连接池可能导致你的应用在池里淹死。
什么是ADO.NET连接池?
ADO.NET连接池是Data Provider提供的一个机制,使得应用程序使用的连接保存在连接池里而避免每次都要完成建立/关闭连接的完整过程。要理解连接池,先要理解程序里SqlConnection.Open()、SqlConnection.Close()和打开/关闭一个“物理连接”的关系。
Data Provider在收到连接请求时建立连接的完整过程是:先连接池里建立新的连接(即“逻辑连接”),然后建立该“逻辑连接”对应的“物理连接”。建立“逻辑连接”一定伴随着建立“物理连接”。Data Provider关闭一个连接的完整过程是先关闭“逻辑连接”对应的“物理连接”然后销毁“逻辑连接”。销毁“逻辑连接”一定伴随着关闭“物理连接”。SqlConnection.Open()是向Data Provider请求一个连接,Data Provider不一定需要完成建立连接的完整过程,可能只需要从连接池里取出一个可用的连接就可以;SqlConnection.Close()是请求关闭一个连接,Data Provider不一定需要完成关闭连接的完整过程,可能只需要把连接释放回连接池就可以。
下面以一个例子来说明。本文例子都使用Console Application。我们使用操作系统的性能监视器来比较使用连接池与否,数据库的“物理连接”数量的不同。因为性能监视器至少每一秒采集一次数据,为方便观察效果,代码中Open和Close连接后都Sleep一秒。
- SqlConnection con = new SqlConnection("server = .;
- database = northwind;pooling = false;trusted_connection = true");
- for(int i = 0;i < 10;i++)
- {
- try
- {
- con.Open();
- System.Threading.Thread.Sleep(1000);
- }
- catch(Exception e){Console.WriteLine(e.Message);}
- finally
- {
- con.Close();
- System.Threading.Thread.Sleep(1000);
- }
- }
首先,不使用ADO.NET连接池做测试。以上程序中pooing = false表示不使用连接池,程序使用同一个连接串Open & Close了10次连接,使用性能计数器观察SQL Server的“物理连接”数量。从下面的锯齿图可以看出每执行一次con.Open(),SQLServer的“物理连接”数量都增加一,而每执行一次con.Close(),SQLServer的“物理连接”数量都减少一。由于不使用连接池,每次Close连接的时候Data Provider需要把“逻辑连接”和“物理连接”都销毁了,每次Open连接的时候Data Provider需要 建立“逻辑连接”和“物理连接”,锯齿图因此而成。
下面启用连接池再测试一次。把连接串的pooling参数改为true,另外在for循环后加上Console.Read()。
从下图可以看出,从第一次Open到第执行完Console.Read()这段时间内,SQL Server的“物理连接”数量一直保持为1,直到关闭console应用程序的进程后SQL Server的“物理连接”数量才变为0。由于使用了连接池,每次Close连接的时候Data Provider只需把“逻辑连接”释放回连接池,对应的“物理连接”则保持打开的状态。每次Open连接的时候,Data Provider只需从连接池取出一个“逻辑连接”,这样就可以使用其对应“物理连接”而不需建立新的“物理连接”,直线图因此而成。