SQLSERVER连接池内部机制
前言介绍:
当应用程序运行的时候,会有一个连接池的管理控件运行在应用程序的进程里,统一管理应用程序和SQLSERVER建立的所有连接,
并且维护这些连接一直处于活动状态。当有用户发出一个connection open指令时连接池会在自己维护的连接池中找一个处于空闲状态
的连接放回自己管理的连接池里,给这个用户使用。当用户使用完毕后,发出connection close指令,连接池会把这个连接放回自己
管理的连接池里,让他重新处于空闲状态,而不是真的从SQL里登出。这样如果下次有用户需要相同连接,就可以重用这个连接,
而无须再去做物理连接了。就是说连接池是放在客户端的,是客户端机制
连接池内部:
连接池内部实际上就是一个线程池,这个线程池是由连接池的管理控件管理的(说白了就是:客户端数据库驱动程序)
客户端应用程序通过加载SQLSERVER的数据驱动控件做SQLSERVER连接。目前客户端数据库驱动程序主要有3种:
1、MDAC(微软数据访问组件) SQL2000的时候开始有的
2、SQLSERVER Native Client SQL2005开始引入的
3、Microsoft JDBC Provider 使用机制与MDAC和SQLSERVER Native Client不同
ADO跟ADO.NET使用的是SQLSERVER Native Client
有些人会问,这个线程池是不是Windows提供的线程池,因为Windows本来就有一个线程池。
本人觉得不是Windows的线程池,因为在连接字符串里面可以指定连接数,如果指定连接数
是32767(即SQLSERVER的最大连接数),应用程序依然可以运行,Windows的线程池
并没有32767那么多,具体数量我也忘记了。
所以线程池应该是控件自己实现的:控件创建一个线程池,然后创建连接字符串里指定的线程数然后放入线程池
同一个客户端数据库驱动程序实现的线程池只能给同样的利用该客户端数据库驱动程序连接SQLSERVER的程序使用
比如:JDBC的线程池只能给同样是JAVA的程序使用,SQLSERVER Native Client的线程池只能给ADO跟ADO.NET
程序使用!!!
多个应用程序使用同一个线程池,那么这些应用程序是如何区分和隔离的?
答案是通过应用程序的名字
比如有两个连接:他们的属性(程序名称)有所不同,那么连接池会创建两个物理连接而不是重用同一个连接
如果两个应用程序的连接字符串里指定了最大连接数是40000,那么管理控件就会创建80000个连接,然后
当应用程序发起连接的时候连接池根据应用程序名来区分该应用程序使用哪一个40000个连接
不明白的童鞋可以看下图,下图解释的会比较清楚
既然连连接池是应用程序开启的,那么如何清理连接池呢?
方法:重启应用程序(强制清理连接池)
最后有一个问题:
两个应用程序都指定连接池的最大连接数为40000,如果是这样的话应该SQLSERVER应该预先
保持了80000个活动连接,让应用程序连接进来,这样SQLSERVER应该会报错
SQLSERVER的最大连接数是32767
但是程序却捕获不了错误信息,那么SQLSERVER会不会一次打开80000个连接并
对这些连接进行维护呢?
答案在我的另一篇文章里:
非常老的话题 SQLSERVER连接池
其实ODBC连接方式也使用了连接池的,大家可以在控制面板-》数据库(ODBC)里看到下面的选项