案例分析:连接池(connection pooling)与阻塞 连接池与SQLSERVER

--案例分析:连接池(connection pooling)与阻塞  连接池与SQLSERVER

--连接池与SQLSERVER
--从客户端建立一个SQL数据库连接,会包含若干个比较费事的步骤。
--首先,客户端要同SQL服务器建立一个物理连接(包括TCP socket或命名管道)
--两台机器相互握手,服务器分析客户端发来的连接字符串,进行身份认证,
--在SQL里建立连接,分配资源等。当客户端关闭连接时,SQL要清除这个
--SQL连接,两台机器会中断物理上的连接。而一般应用程序,虽然可能会
--同时建立很多连接,不断地登入登出SQL,但是这些连接一般用的都是同一个
--用户或一组用户。所以对SQL来讲,应用程序是在不停地建立和关闭同样
--的连接。这是一种浪费资源的做法

--为了提高应用程序效率,大部分SQL客户端编程接口,包括ADO和ADO.NET
--都支持连接池(connection pooling)这种机制,以减少SQL端的登入和
--登出数目。当应用程序运行的时候,会有一个连接池的管理控件运行在
--应用程序的进程里,统一管理应用程序和SQL建立的所有连接,并且维护
--这些连接一直处于活动状态。当有用户发出一个connection open指令时
--连接池会在自己维护的连接池中找一个处于空闲状态的连接放回自己管理
--的连接池里,给这个用户使用。当用户使用完毕后,发出connection close
--指令,连接池会把这个连接放回自己管理的连接池里,让他重新处于空闲
--状态,而不是真的从SQL里登出。这样如果下次有用户需要相同连接,就可以
--重用这个连接,而无须再去做物理连接了


--当应用程序总是使用同样的连接字符串,申请数据库连接的时候,连接池机制
--总是能够维护一定量的活动连接给用户反复使用,大大减少了实际的连接数目
--和登入登出次数。所以他能够大大提高应用程序的速度,同时减轻SQL的负担
--对于使用ADO或ADO.NET开发的程序,连接池是默认开启的


--连接池是一个客户端机制。虽然用户使用了open和close指令,不停地开启
--和关闭连接,但对SQL来讲,这个连接始终是一个,和其他形式建立的连接
--相比没有任何特殊的地方。我们知道,每个连接都会维护自己的一些独有
--资源,比如临时表,变量,游标等,他也有可能会修改一些默认的设置,
--例如事务隔离级别等。如果不同用户先后使用同一个连接,会不会前一个
--用户设置的状态或申请的资源影响后一个用户正常使用呢?如果连接池
--的管理者不做特殊处理,的确会有这种情况发生。所以微软的连接池技术里
--包括ADO.NET和ADO,引入了一个特殊的指令:sp_reset_connection,来
--清除前一个用户做的绝大多数设置,避免这种问题。


--sp_reset_connection会在SQLSERVER里做些什么?
--1、清除连接现有所有内部数据结构。包括:
--(1)清除所有openxml打开的document句柄
--(2)关闭所有的游标(cursor)
--(3)释放所有SQL语句句柄
--(4)清除所有临时对象(临时表等)
--(5)释放连接持有的所有锁
--(6)清除缓存的所有安全上下文信息(security context)

--2、重置连接设置。包括:
--(1)重置连接的SQL Trace标志值(例如1204,1222,3604等)
--(2)重置所有"SET" 选项值(SET IMPLICIT_TRANSACTIONS ON 等)
--(3)重置连接的统计信息值


--3、回滚所有SQLSERVER事务
--需要说明的是,如果连接当前参与了一个由客户端发起的分布式事务,这个分布式事务
--不会受到影响。在SQL里的事务还会被保留

--4、把当前数据库切换到用户默认数据库

--5、SQLSERVER会再次检查当前用户是否有权做数据库连接。如果这个权力已被移除
--SQLSERVER会中断这个物理连接(这样防止一个已经被取消访问权的用户还能长时间
--使用数据库的问题)

--完成这些事情以后,一个连接基本上已经和他先前做的事情不再有任何关系(分布式事务除外)
--可以说,这个连接和一个新的连接已经没有什么大的区别了。通过这些,应用程序的用户
--可以尽快地拿到和释放连接,而SQLSERVER这边也不会因为连接的重复使用而产生
--相互影响的问题

  

posted @ 2018-04-18 09:38  落霞秋水  阅读(764)  评论(0)    收藏  举报